初入Mongodb

C1.What is MongoDB

MongoDB是一个NoSQL Document DataBase

Document和Collection

  • document指的是一组键值对
  • collection指的是一组document

在一个collection中的document格式可以相同也可以不相同

一个collection中的document空了,那么这个collection也会消失。一个database的document空了,那么这个database也会消失

C2.Importing, Exporting, and Querying Data

MongoDB怎么存储内容

存储方式

JSON格式

  • 解析慢
  • 占用空间
  • 支持的类型少
  • 机器和人可读

BSON格式

以二进制的方式存储并为JSON格式

  • 机器可读

  • 二进制形式

  • 支持类型更多

  • 解析速度更快,占用更少的空间

是哪个?

MongoDB以BSON做传输和储存,以JSON格式看待

导入和导出

JSON

1
2
3
4
5
mongoimport --uri ""

mongoexport --uri ""
--collection=name
--out=name.json

BSON

1
2
3
4
5
mongorestore --uri ""
--drop dump

mongodump --uri ""
--drop=filename.json

query

1
2
3
4
5
6
7
8
9
10
11
show dbs
use sample_training
show collections
#查询 但可能结果很多 一屏幕显示不完(使用"lt"显示下一页结果)
db.zips.find({"state": "NY"})
#计数
db.zips.find({"state": "NY"}).count()
#美化显示
db.zips.find({"state": "NY", "city": "ALBANY"}).pretty()
#随机获取一个
db.inspections.findOne();

C3.Creating and Manipulating Documents

ObjectId

每一个document都默认有一个字段_id,类型为objectId。它是唯一的

insert

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#单插
db.inspections.insert({
...
});

#顺序多插(遇到error即停止后续插入)
db.inspections.insert([{},{},{}])

#无序多插(遇到error不停止,继续后续的插入)
db.inspections.insert([{},{},{}],{"ordered": false})

#mongodb为了简化collection和document的插入
db.inspection.insert([{}]) #db中没有inspection

#但是如果是use inspection是不会新如inspection库,因为没有插入数据
use inspection

update

1
2
3
4
#如果有多个匹配条件的话,只会随机对一个进行操作
updateOne({"f1":v1}, operations)
#批量更新
updateMany({"f1":v1}, “operations”)

operations

1
2
3
4
5
{
<operator1>: { <field1>: <value1>, ... },
<operator2>: { <field2>: <value2>, ... },
...
}

$inc:增加

$set:赋值(如果属性不在,则和push类似)

$push:添加属性和往数组元素

更多见https://www.mongodb.com/docs/manual/reference/operator/update/

例子

将item为paper的size.uom和status进行修改

1
2
3
4
5
6
db.inventory.updateOne(
{ item: "paper" },
{
$set: { "size.uom": "cm", status: "P" }
}
)

delete

1
2
deleteOne({})
deleteMany({})

drop

删除一个collection

1
db.collection_name.drop()

C4.Advanced CRUD Operations

比较符

  • (>) 大于 - $gt
  • (<) 小于 - $lt
  • (>=) 大于等于 - $gte
  • (<= ) 小于等于 - $lte
1
2
db.trips.find({"tripduration":{"$lt":70, "$gt":100}, 
"usertype":{"$eq":"Consumer"}})

逻辑符

  • $and:都满足(默认的情况即是and的效果)
  • $or:其中一个满足
  • $nor:其中一个不满足
  • $not:都不满足

前三个使用类似

1
"<operator>":[{condition1},{condition2}]
1
db.routes().find([{"$or",[{c1},{c}])

not是对带修饰符的condtion语句的修饰

1
dp.routes().find({"src_airport":{"$not":{"$eq":"ASF"}}})

特殊

想表示多个相同逻辑符的表达式的and的时候

必须使用$and逻辑符,而不能用逗号

1
2
3
4
5
6
db.routes.find({ "$and": [ { "$or" :[ { "dst_airport": "KZN" },
{ "src_airport": "KZN" }
] },
{ "$or" :[ { "airplane": "CR2" },
{ "airplane": "A81" } ] }
]}).pretty()

查询表达式符

$col 的意思是取值

查询表达符中的比较符的使用发生了变化,比较符在前,属性名称和值在后

1
2
3
db.trips.find({ "$expr": { "$and": [ { "$gt": [ "$tripduration", 1200 ]},
{ "$eq": [ "$end station id", "$start station id" ]}
]}}).count()

数组相关

$push

先前的update中的$push来实现为文档添加元素,或者将属性从单值转为多值,或向数组中添加元素


我们设定有个文档的amenities的值为[“a”,”b”,”c”]

单个匹配查询

1
find({"amenities":"a"}) --> 能查询到

精确内容和顺序匹配

1
2
find({"amenities":["a","b","c"]}) --->能查询到
find({"amenities":["b","a","c"]}) --->不能查询到

内容匹配

即文档中的amenities数组必须包含a,b,c即可

1
find({"amenities":{"$all":["b","a","c"]}})

长度匹配

1
find("amenities":{"$size":12,"$all":["b","a","c"]})

查询内容限定

1
db.<collection>.find({<query>,<projection>)

1表示展示,0表示隐藏,但两者不能混合着用

特殊的是_id:0,other:1是允许的

1
2
db.listingsAndReviews.find({ "amenities": "Wifi" },
{ "price": 1, "address": 1, "_id": 0 }).pretty()

查询子文档$elemMatch

可能有多个子文档,此时只要有一个满足即匹配

1
2
db.grades.find({"class_id":431},
{"scores":{"$elemMatch":{"score":{"$gt":55}}}})

定位子文档内容

通过field1.field2…来获取子文档field1的field2内容

1
db.trips.findOne({ "start station location.type": "Point" })

定位数组元素

通过array.0.field…来获取数组元素内容

1
db.companies.find({ "relationships.0.person.first_name": "Mark"},{ "name": 1 }).count()

C5.Indexing and Aggregation Pipeline

Aggregation Framework

Mongo的聚合框架类似与Java8的stream API 通过该框架构建自己的数据处理的流水线

基本使用

1
db.<collection>.aggregate()

数据处理符

$match

内容匹配处理

1
db.collection.aggregate({"$match":{"field":"value"}})

$project

数据映像,跟find中的数据映像类似

1
db.collection.aggregate({"$project":{"field":1/0}})

$group

汇聚数据

  • _id:组合数据的字段
1
2
db.collection.aggregate([{"$group":{"_id":"$field",
"count":{"$sum",1}}}])

多处理

1
2
3
db.collection.aggregate([{"$match":{}},
{"$project":{}}
}])

sort & limit

sort可以用多字段排序,而1代表顺序,-1代表逆序

1
db.<collection>.sort({"field1":"1","field2":"-1"})
1
db.<collection>.limit()

对于sort和limit的使用,无论sort和limit的调用顺序如何都是先sort再limit

值得注意的是,null会在升序排序的最前

indexes

索引这块的机制和Mysql的类似,也有覆盖索引的机制

单一索引

1
db.trips.createIndex({ "birth year": 1 }) 

复合索引

1
db.trips.createIndex({ "start station id": 1, "birth year": 1 })

upsert

常见的场景是某属性内容存在即更新,不存在则插入

mongo中的upsert即是,当query返回结果为空时,进行插入

1
db.iot.updateOne(<query>,<update>,{"upsert": true })

sample

1
2
3
4
5
db.iot.updateOne({ "sensor": r.sensor, "date": r.date,
"valcount": { "$lt": 48 } },
{ "$push": { "readings": { "v": r.value, "t": r.time } },
"$inc": { "valcount": 1, "total": r.value } },
{ "upsert": true })

初入Mongodb
https://dada404.github.io/2022/06/05/5_%E6%9C%8D%E5%8A%A1%E7%9B%B8%E5%85%B3/1_Mongodb/%E5%88%9D%E5%85%A5Mongodb/
作者
Reeda
发布于
2022年6月5日
许可协议