CnSwift - 雨燕

agile development - 敏捷开发

Mongodb入门与实践

Mongodb入门与实践

Mac安装MongoDB

brew install mongodb

使用Homebrew成功安装MongoDB

1
2
3
4
To have launchd start mongodb now and restart at login:
brew services start mongodb
Or, if you don't want/need a background service you can just run:
mongod --config /usr/local/etc/mongod.conf

Mac启动MongoDB

sudo mongod --config /usr/local/etc/mongod.conf

Mac连接MongoDB,另打开一个终端

mongo

MongoDB基本操作CRUD

创建文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
> show dbs # 查看数据库列表
admin 0.000GB
local 0.000GB
tutorial 0.000GB
> db # 查看当前所在数据库
test
> use myblog # 选择数据库
switched to db blog
> db
myblog
> post = {"title" : "My Blog Post",
... "content" : "Here's my blog post",
... "date" : new Date()} # 创建变量,表示我们的MongoDB文档
{
"title" : "My Blog Post",
"content" : "Here's my blog post",
"date" : ISODate("2017-08-22T03:03:11.266Z")
}
> db.blog.insert(post) # 插入数据,将MongoDB文档保存到blog集合
WriteResult({ "nInserted" : 1 })
> users = [{"uid" : 1}, {"uid" : 2}, {"uid" : 3}]
[ { "uid" : 1 }, { "uid" : 2 }, { "uid" : 3 } ]
> db.blog.insert(users) # 批量插入,接收的参数是一个文档数组
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 3,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
> db.blog.find()
{ "_id" : ObjectId("599e39e0a159b0cdf87feb8e"), "uid" : 1 }
{ "_id" : ObjectId("599e39e0a159b0cdf87feb8f"), "uid" : 2 }
{ "_id" : ObjectId("599e39e0a159b0cdf87feb90"), "uid" : 3 }
> show collections; # 查看集合列表
food
users
>

读取文档

1
2
3
4
5
6
7
8
9
10
> db.blog.find() # 查看多个文档,最多显示20个,"_id"为额外添加的键
{ "_id" : ObjectId("599b9f05a159b0cdf87feb8d"), "title" : "My Blog Post", "content" : "Here's my blog post", "date" : ISODate("2017-08-22T03:03:11.266Z") }
> db.blog.findOne() # 查看1个文档
{
"_id" : ObjectId("599b9f05a159b0cdf87feb8d"),
"title" : "My Blog Post",
"content" : "Here's my blog post",
"date" : ISODate("2017-08-22T03:03:11.266Z")
}
>

更新文档之文档替换

1
2
3
4
5
6
7
> post.comments = []
[ ]
> db.blog.update({title : "My Blog Post"}, post) # 更新文档,添加一个新的键comments,update接收两个参数,第一个是限定条件(必须唯一,否则更新就会失败),第二个是新的文档
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.find()
{ "_id" : ObjectId("599b9f05a159b0cdf87feb8d"), "title" : "My Blog Post", "content" : "Here's my blog post", "date" : ISODate("2017-08-22T03:03:11.266Z"), "comments" : [ ] }
>

更新文档之使用修改器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> post = {"id" : 1,
... "views" : 100
... }
{ "id" : 1, "views" : 100 }
> db.blog.insert(post)
WriteResult({ "nInserted" : 1 })
> db.blog.find()
{ "_id" : ObjectId("599e6555a159b0cdf87feb91"), "id" : 1, "views" : 100 }
> db.blog.update({"id" : 1},
... {"$inc" : {"views" : 1}}) # 使用$inc修改器增加已有的键views的值,如果该键不存在那就创建一个,$inc只能用于整型、长整型或双精度浮点型的值,使用修改器时,"_id"的值不能改变,其它键值,包括其它唯一索引的键,都是可以更改的。
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.find()
{ "_id" : ObjectId("599e6555a159b0cdf87feb91"), "id" : 1, "views" : 101 }
> db.blog.update({"id" : 1}, {"$set" : {"comments" : 50}}) # $set修改器用于指定一个字段的值,如果这个字段不存在,则创建它。可用于增加自定义键或者更新已有的键值。
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.find()
{ "_id" : ObjectId("599e6555a159b0cdf87feb91"), "id" : 1, "views" : 100, "comments" : 50 }
> db.blog.update({"id" : 1}, {"$unset" : {"comments" : 1}}) # 使用$unset修改器删除键
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.find()
{ "_id" : ObjectId("599e6555a159b0cdf87feb91"), "id" : 1, "views" : 100 }
>

更新文档之数组修改器

$push

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> post = {"id" : 1,
... "title" : "My Blog Post",
... "content" : "Here's my blog post"
... }
{ "id" : 1, "title" : "My Blog Post", "content" : "Here's my blog post" }
> db.blog.insert(post)
WriteResult({ "nInserted" : 1 })
> db.blog.find()
{ "_id" : ObjectId("599f8c6da159b0cdf87feb92"), "id" : 1, "title" : "My Blog Post", "content" : "Here's my blog post" }
> db.blog.update({"title" : "My Blog Post"},
... {"$push" : {"comments" :
... {"name" : "joe", "content" : "nice post"}}}) # 如果数组已存在,$push会向已有的数组末尾加入一个元素,要是没有就创建一个新的数组
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.find()
{ "_id" : ObjectId("599f8c6da159b0cdf87feb92"), "id" : 1, "title" : "My Blog Post", "content" : "Here's my blog post", "comments" : [ { "name" : "joe", "content" : "nice post" } ] }
> db.blog.update({"title" : "My Blog Post"},
... {"$push" : {"comments" :
... {"name" : "bob", "content" : "nice post"}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.find()
{ "_id" : ObjectId("599f8c6da159b0cdf87feb92"), "id" : 1, "title" : "My Blog Post", "content" : "Here's my blog post", "comments" : [ { "name" : "joe", "content" : "nice post" }, { "name" : "bob", "content" : "nice post" } ] }
>

$each

1
2
3
4
5
6
> db.blog.update({"title" : "My Blog Post"},
... {"$push" : {"tags" : {"$each" : ["tag1", "tag2"]}}}) # 使用$each子操作符,可以通过一次$push操作添加多个值,如果指定的数组只含有一个元素,那这个操作符就等同于没有使用$each的普通$push操作
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.find()
{ "_id" : ObjectId("599f8c6da159b0cdf87feb92"), "id" : 1, "title" : "My Blog Post", "content" : "Here's my blog post", "comments" : [ { "name" : "joe", "content" : "nice post" }, { "name" : "bob", "content" : "nice post" } ], "tags" : [ "tag1", "tag2" ] }
>

$slice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> post = {"title" : "My Blog Post",
... "content" : "Here's my blog"}
{ "title" : "My Blog Post", "content" : "Here's my blog" }
> db.blog.insert(post)
WriteResult({ "nInserted" : 1 })
> db.blog.find()
{ "_id" : ObjectId("599f9a09a159b0cdf87feb93"), "title" : "My Blog Post", "content" : "Here's my blog" }
> db.blog.update({"title" : "My Blog Post"},
... {"$push" : {"tags" : {"$each" : ["tag1", "tag2", "tag3"],
... "$slice" : -2}}}) # $slice和$push组合在一起使用,可以保证数组不超过最大长度(2),如果数组元素数量小于最大长度(2),那么所有元素都会保留,如果数组元素数量大于最大长度,那么只有最后最大长度数量(2)个元素会保留,注意$slice的值必须是负整数,且不能单独与$push配合使用,必须使用$each
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.blog.find()
{ "_id" : ObjectId("599f9a09a159b0cdf87feb93"), "title" : "My Blog Post", "content" : "Here's my blog", "tags" : [ "tag2", "tag3" ] }
>

$sort

1
2
3
4
5
6
7
> db.blog.update({"title" : "My Blog Post"},
... {"$push" : {"$tags" : {"$each" : ["tags4", "tags5", "tags6", "tags7", "tags8", "tags9", "tags10"],
... "$slice" : -5,
... "$sort" : {"tags" : -1}}}}) # 可以在$slice清理元素之前使用$sort排序,不能单独与$push配合使用,必须使用$each
> db.blog.find()
{ "_id" : ObjectId("599f9a09a159b0cdf87feb93"), "title" : "My Blog Post", "content" : "Here's my blog", "tags" : [ "tags6", "tags7", "tags8", "tags9", "tags10" ] }
>

将数组作为数据集使用

$ne

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
> users = {"admin" : ["admin1", "admin2"],
... "member" : ["member1", "member2"]}
{
"admin" : [
"admin1",
"admin2"
],
"member" : [
"member1",
"member2"
]
}
> db.users.insert(users)
WriteResult({ "nInserted" : 1 })
> db.users.find()
{ "_id" : ObjectId("599fe3c5a159b0cdf87feb95"), "admin" : [ "admin1", "admin2" ], "member" : [ "member1", "member2" ] }
> db.users.update({"admin" : {"$ne" : "admin3"}},
... {$push : {"admin" : "admin3"}}) # 使用$ne查询要添加的数组元素是否在数组中已经存在,如果不存在,就添加进去
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : ObjectId("599fe3c5a159b0cdf87feb95"), "admin" : [ "admin1", "admin2", "admin3" ], "member" : [ "member1", "member2" ] }
> db.users.update({"admin" : {"$ne" : "admin3"}}, {$push : {"admin" : "admin3"}})
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
> db.users.find()
{ "_id" : ObjectId("599fe3c5a159b0cdf87feb95"), "admin" : [ "admin1", "admin2", "admin3" ], "member" : [ "member1", "member2" ] }
>

$addToSet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
> users = {"username" : "bob",
... "email" : ["bob@qq.com", "bob@gmail.com"]}
{ "username" : "bob", "email" : [ "bob@qq.com", "bob@gmail.com" ] }
> db.users.insert(users)
WriteResult({ "nInserted" : 1 })
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@qq.com", "bob@gmail.com" ] }
> db.users.update({"username" : "bob"},
... {"$addToSet" : {"email" : "bob@qq.com"}}) # 使用$addToSet可以避免插入重复元素
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@qq.com", "bob@gmail.com" ] }
> db.users.update({"username" : "bob"},
... {"$addToSet" : {"email" : "bob@hotmail.com"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@qq.com", "bob@gmail.com", "bob@hotmail.com" ] }
> db.users.update({"username" : "bob"},
... {"$addToSet" : {"email" : {"$each" : ["bob@126.com", "bob@163.com"]}}}) # 使用$addToSet和$each组合起来,可以添加多个不同的值
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@qq.com", "bob@gmail.com", "bob@hotmail.com", "bob@126.com", "bob@163.com" ] }
>

删除元素

$pop,$pull

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> db.users.update({"username" : "bob"},
... {"$pop" : {"email" : -1}}) # $pop从数组任何一段删除元素,正整数从末尾删除,负整数从头部删除
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@gmail.com", "bob@hotmail.com", "bob@126.com", "bob@163.com" ] }
> db.users.update({"username" : "bob"}, {"$pop" : {"email" : 1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@gmail.com", "bob@hotmail.com", "bob@126.com" ] }
> db.users.update({"username" : "bob"},
... {"$pull" : {"email" : "bob@hotmail.com"}}) # $pull将匹配特定条件的文档全部删除
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@gmail.com", "bob@126.com" ] }
>

基于位置的数组修改器

1
2
3
4
5
6
7
8
9
10
11
12
13
> db.users.update({"username" : "bob"},
... {"$set" : {"email.0" : "bob@163.com"}}) # 可以将下标直接作为键来选择元素
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
"_id" : ObjectId("599fe8a3a159b0cdf87feb96"),
"username" : "bob",
"email" : [
"bob@163.com",
"bob@126.com"
]
}
>

upsert

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> db.users.findOne()
{
"_id" : ObjectId("599fe8a3a159b0cdf87feb96"),
"username" : "bob",
"email" : [
"bob@163.com",
"bob@126.com"
]
}
> db.users.update({"username" : "bob"}, {"$inc" : {"score" : 80}}, true) # 第三个参数true表示这是个upsert,upsert是个特殊的更新,如果没有找到符合更新条件的文档,就会以这个条件和更新文档为基础,创建一个新的文档。如果找到了匹配的文档,则正常更新。
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.users.findOne()
{
"_id" : ObjectId("599fe8a3a159b0cdf87feb96"),
"username" : "bob",
"email" : [
"bob@163.com",
"bob@126.com"
],
"score" : 80
}
>

更新多个文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 160 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 160 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 160 }
> db.users.update({"score" : 160}, {"$set" : {"score" : 100}}, false, true) # 默认情况下,更新只能对匹配条件的第一个文档执行操作。如果多个文档符合条件,只有第一个文档会被更新,其它文档不会发生变化。要更新所有匹配文档,可以将update的第四个参数设置为true。注意:第3个参数表示更新是否是upsert更新。
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 100 }
> db.users.update({"score" : 100}, {"$set" : {"score" : 60}}, false, true)
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })
> db.runCommand({getLastError : 1}) # 运行getLastError命令(可以理解为返回最后一次操作的相关信息)。键n的值就是被更新的数量,updatedExisting为true,表示对已有的文档进行更新。
{
"connectionId" : 1,
"updatedExisting" : true,
"n" : 3,
"syncMillis" : 0,
"writtenTo" : null,
"err" : null,
"ok" : 1
}
>

返回被更新的文档findAndModify

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 60 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 60 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
> db.runCommand({"findAndModify" : "users",
... "query" : {"score" : 60},
... "sort" : {"score" : -1},
... "update" : {"$set" : {"score" : 100}}}) # 字段说明:findAndModify字符串,集合名;query查询文档,用于检索文档的条件;sort排序结果的条件;update修改器文档,用于对匹配的文档进行更新(update和remove必须且只能指定一个);remove布尔类型,表示是否删除文档(remove和update必须且只能指定一个);new布尔类型,表示返回更新前的文档还是更新后的文档,默认是更新前的文档;fields文档中需要返回的字段(可选);upsert布尔类型,值为true时表示这是一个upsert,默认是false。
{
"lastErrorObject" : {
"updatedExisting" : true,
"n" : 1
},
"value" : {
"_id" : ObjectId("599fe8a3a159b0cdf87feb96"),
"username" : "bob",
"email" : [
"bob@163.com",
"bob@126.com"
],
"score" : 60
},
"ok" : 1
}
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 60 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
>

删除文档

1
2
3
4
> db.blog.remove({title : "My Blog Post"}) # remove将文档从数据库中永久删除,接收一个限定条件的文档作为参数,如果没有使用任何参数,会将集合内的所有文档全部删除,但不会删除集合本省,也不会删除集合的元信息,缺点是比drop删除速度慢
WriteResult({ "nRemoved" : 1 })
> db.blog.find()
>

drop删除

1
2
3
4
5
> db.blog.drop() # 比remove删除速度快,缺点是不能指定任何限定条件,整个集合和元数据都被删除了
true
> db.blog.findOne()
null
>

查询

find简介

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> db.users.find() # 空的查询文档,会匹配集合的全部内容
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
> db.users.find({"score" : 100}) # 向查询文档中添加键/值对时,就意味着限定了查询条件
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
> db.users.find({"username" : "joy", "score" : 100}) # 可以向查询文档中添加多个键/值对,用逗号分隔,多个查询条件组合在一起,会被解释为条件1AND条件2...AND条件N
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
> db.users.find({}, {"username" : 1, "email" : 1}) # 通过第二个参数可以指定想要返回的键,值为1表示返回,值为0表示剔除
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ] }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ] }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ] }
> db.users.find({}, {"username" : 1, "email" : 1, "_id" : 0})
{ "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ] }
{ "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ] }
{ "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ] }
>

查询条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> db.users.find({"score" : {"$lt" : 100}}) # $lt小于
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
> db.users.find({"score" : {"$lte" : 100}}) # $lte小于等于
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
> db.users.find({"score" : {"$gt" : 60}}) # $gt大于
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
> db.users.find({"score" : {"$gte" : 60}}) # $gte大于等于
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
> db.users.find({"score" : {"$lte" : 100, "$gte" : 60}}) # 组合使用
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
> db.users.find({"username" : {"$ne" : 'joy'}}) # $ne不等于
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
>

OR查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> db.users.find({"score" : {"$in" : [100, 60]}}) # $in匹配多个值
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
> db.users.find({"score" : {"$nin" : [60, 80]}}) # $nin不匹配多个值
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
> db.users.find({"$or" : [{"username" : "lucy"}, {"score" : 100}]}) # $or包含多个匹配条件
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
> db.users.find({"$or" : [{"username" : {"$in" : ["bob", "joy"]}}, {"score" : 60}]}) # $or可以包含其它条件
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
>

$not

1
2
3
4
> db.users.find({"score" : {"$not" : {"$in" : [60, 80]}}}) # $not用来查找那些与特定模式不匹配的文档
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
>

特定类型查询

null

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> db.users.insert({"username" : "lily", "email" : null, "score" : 80})
WriteResult({ "nInserted" : 1 })
> db.users.find()
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
{ "_id" : ObjectId("59b89d85a159b0cdf87feb99"), "username" : "lily", "email" : null, "score" : 80 }
> db.users.find({"email" : null}) # null不仅会匹配某个键的值为null的文档,而且还会匹配不包含这个键的文档
{ "_id" : ObjectId("59b89d85a159b0cdf87feb99"), "username" : "lily", "email" : null, "score" : 80 }
> db.users.find({"tel" : null})
{ "_id" : ObjectId("599fe8a3a159b0cdf87feb96"), "username" : "bob", "email" : [ "bob@163.com", "bob@126.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf1ffa159b0cdf87feb97"), "username" : "joy", "email" : [ "joy@126.com", "joy@163.com" ], "score" : 100 }
{ "_id" : ObjectId("59acf261a159b0cdf87feb98"), "username" : "lucy", "email" : [ "lucy@126.com", "lucy@163.com" ], "score" : 60 }
{ "_id" : ObjectId("59b89d85a159b0cdf87feb99"), "username" : "lily", "email" : null, "score" : 80 }
> db.users.find({"email" : {"$in" : [null], "$exists" : true}})
{ "_id" : ObjectId("59b89d85a159b0cdf87feb99"), "username" : "lily", "email" : null, "score" : 80 }
> db.users.find({"tel" : {"$in" : [null], "$exists" : true}}) # 如果仅想匹配键值为null的文档,既要检查该键的值是否为null,还要通过$exists判定键值已存在
>

查询数组

$all

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> db.food.insert({"fruit" : ["apple", "banana", "peach"]})
WriteResult({ "nInserted" : 1 })
> db.food.find({"fruit" : "banana"}) # 查询数组元素和查询标量值是一样的。
{ "_id" : ObjectId("59b8a605a159b0cdf87feb9a"), "fruit" : [ "apple", "banana", "peach" ] }
> db.food.insert({"fruit" : ["apple", "kumquat", "orange"]})
WriteResult({ "nInserted" : 1 })
> db.food.insert({"fruit" : ["cherry", "banana", "apple"]})
WriteResult({ "nInserted" : 1 })
> db.food.find({"fruit" : {"$all" : ["apple", "banana"]}}) # 使用$all可以通过多个元素匹配数组
{ "_id" : ObjectId("59b8a605a159b0cdf87feb9a"), "fruit" : [ "apple", "banana", "peach" ] }
{ "_id" : ObjectId("59b8a8bba159b0cdf87feb9c"), "fruit" : [ "cherry", "banana", "apple" ] }
> db.food.find({"fruit.2" : "peach"}) # 查询数组特定位置的元素,需要使用key.index语法指定下标,数组下标都是从0开始
{ "_id" : ObjectId("59b8a605a159b0cdf87feb9a"), "fruit" : [ "apple", "banana", "peach" ] }
>

$size

1
2
3
4
5
6
> db.food.find({"fruit" : {"$size" : 3}}) # $size查询特定长度的数组
{ "_id" : ObjectId("59b8a605a159b0cdf87feb9a"), "fruit" : [ "apple", "banana", "peach" ] }
{ "_id" : ObjectId("59b8a89aa159b0cdf87feb9b"), "fruit" : [ "apple", "kumquat", "orange" ] }
{ "_id" : ObjectId("59b8a8bba159b0cdf87feb9c"), "fruit" : [ "cherry", "banana", "apple" ] }
> db.food.find({"fruit" : {"$size" : 2}})
>

$slice操作符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
> db.blogs.insert({"title" : "This is my blog title", "content" : "This is my blog content", "comments" : [{"name" : "joe", "email" : "joe@example.com", "content" : "nice post."}, {"name" : "bob", "email" : "bob@example.com", "content" : "good post."}, {"name" : "lucy", "email" : "lucy@example.com", "content" : "beautiful post."}]})
WriteResult({ "nInserted" : 1 })
> db.blogs.findOne()
{
"_id" : ObjectId("59c0b66aa159b0cdf87feb9d"),
"title" : "This is my blog title",
"content" : "This is my blog content",
"comments" : [
{
"name" : "joe",
"email" : "joe@example.com",
"content" : "nice post."
},
{
"name" : "bob",
"email" : "bob@example.com",
"content" : "good post."
},
{
"name" : "lucy",
"email" : "lucy@example.com",
"content" : "beautiful post."
}
]
}
> db.blogs.findOne({}, {"comments" : {"$slice" : 2}}) # $slice操作符可以返回某个键匹配的数组元素的一个子集。例如,我们返回前2条评论。
{
"_id" : ObjectId("59c0b66aa159b0cdf87feb9d"),
"title" : "This is my blog title",
"content" : "This is my blog content",
"comments" : [
{
"name" : "joe",
"email" : "joe@example.com",
"content" : "nice post."
},
{
"name" : "bob",
"email" : "bob@example.com",
"content" : "good post."
}
]
}
> db.blogs.findOne({}, {"comments" : {"$slice" : -2}}) # 返回后2条评论
{
"_id" : ObjectId("59c0b66aa159b0cdf87feb9d"),
"title" : "This is my blog title",
"content" : "This is my blog content",
"comments" : [
{
"name" : "bob",
"email" : "bob@example.com",
"content" : "good post."
},
{
"name" : "lucy",
"email" : "lucy@example.com",
"content" : "beautiful post."
}
]
}
> db.blogs.findOne({}, {"comments" : {"$slice" : [2, 3]}}) # 返回第3个到第5个评论,如果数组不够5个元素,则返回第3个后面的所有元素。
{
"_id" : ObjectId("59c0b66aa159b0cdf87feb9d"),
"title" : "This is my blog title",
"content" : "This is my blog content",
"comments" : [
{
"name" : "lucy",
"email" : "lucy@example.com",
"content" : "beautiful post."
}
]
}
>

返回一个匹配的数组元素

1
2
3
> db.blogs.find({"comments.name" : "bob"}, {"comments.$" : 1}) # 使用$操作符返回与查询条件相匹配的任意一个数组元素,注意,这样只会返回第一个匹配的文档。
{ "_id" : ObjectId("59c0b66aa159b0cdf87feb9d"), "comments" : [ { "name" : "bob", "email" : "bob@example.com", "content" : "good post." } ] }
>

数组和范围查询的相互作用

感谢赞赏.

Welcome to my other publishing channels