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
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
汇聚数据
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"})
|
对于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 })
|