如果数据库中尚未有数据, 准备测试数据
db.test1.insertMany([ {"name": "zhangsan", "age": 19, "score": [90, 80]}, {"name": "lisi", "age": 29, "score": [40, 60]}, {"name": "xiaoming", "age": 18, "score": [20, 40]}, {"name": "xiaohong"} ])
第一部分 元素操作符
1. $exists: 判断指定字段是否存在,并返回相应的结果 2. $type: 匹配字段对应的类型
1.1 $exists
{ field: { $exists: <boolean> } }
判断指定字段是否存在,并返回相应的结果, 直接上代码
{"$exists": true}
> db.test1.find({"qty": {"$exists": true}})#张三存在qty属性, 就返回该条数据{ "_id" : ObjectId("58c8dc54ef9b994487420f29"), "name" : "zhangsan", "age" : 19, "score" : [ 90, 80 ], "qty" : 10 }
{"$exists": false}
> db.test1.find({"qty": {"$exists": false}})#以下三条数据均不存在qty字段{ "_id" : ObjectId("58c8dc54ef9b994487420f2a"), "name" : "lisi", "age" : 29, "score" : [ 40, 60 ] } { "_id" : ObjectId("58c8dc54ef9b994487420f2b"), "name" : "xiaoming", "age" : 18, "score" : [ 20, 40 ] } { "_id" : ObjectId("58c9e4b80c4d4cf6f4563b26"), "name" : "xiaohong" }
1.2 $type
$type文档
{ field: { $type: <BSON type number> | <String alias> } }
第二部分
1. $mod 模运算 2. $regex 正则表达 3. $text 文本搜索 4. $where: 支持js表达式
2.1 $mod运算
db.users.find('this.age % 6 == 0'); 或者 > db.users.find({"age" : {$mod : [6, 0]}}); { "_id" : ObjectId("58d21667edca14f0f7ffbedb"), "name" : "xiaoming", "age" : 18, "score" : [ 20, 40 ] }
2.2 $regex 正则表达
匹配正则表达式
注: 之后后专门整理一篇正则表达式的文章
2.3 $text
全文本搜索
2.4 where
第三部分
1. $all: 匹配数组中包含query中的元素 2. $elemMatch : 筛选数组中的元素 3. $size: 匹配数组中元素的个数.
3.1 $all
{ <field>: { $all: [ <value1> , <value2> ... ] } }
官方实例
{ tags: { $all: [ "ssl" , "security" ] } } 等价于 { $and: [ { tags: "ssl" }, { tags: "security" } ] }
为了便于理解, 在此修改一下测试数据
, 将小明的成绩改为三个数字
> db.users.update({"name": "xiaoming"}, {"$push": {"score": 100}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
此时两种成功的筛选数据的方式, 得到结果
#测试数据在最上边,必须同时满足score包含备选数据, [子集与真子集]> db.users.find({"score": {"$all": [20, 40]}}) { "_id" : ObjectId("58d21667edca14f0f7ffbedb"), "name" : "xiaoming", "age" : 18, "score" : [ 20, 40, 100 ] } > db.users.find({"score": {"$all": [20, 40, 100]}}) { "_id" : ObjectId("58d21667edca14f0f7ffbedb"), "name" : "xiaoming", "age" : 18, "score" : [ 20, 40, 100 ] }
无结果数据
#没有任何一条数据的score**同时**包含20 60> db.users.find({"score": {"$all": [20, 60]}}) >
总结 X$in 与 $all的区别
用实例告诉大家的区别
x.1 $in
原始数据中只要包含一条或多条
备选数据, 即满足
> db.users.find({"score": {"$in": [20, 60]}}) { "_id" : ObjectId("58d21667edca14f0f7ffbeda"), "name" : "lisi", "age" : 29, "score" : [ 40, 60 ] } { "_id" : ObjectId("58d21667edca14f0f7ffbedb"), "name" : "xiaoming", "age" : 18, "score" : [ 20, 40, 100 ] }
x.2 $all 原始数据必须完整的包含或等于
被选数据
#为空> db.users.find({"score": {"$all": [20, 60]}}) >
3.2 $elemMatch
语法
{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }
实例一
筛选数组中包含 大于50小于100的数据
, 只要属于其子集即可
> db.users.find({"score": {"$elemMatch": {"$gt": 50, "$lt": 100}}}) { "_id" : ObjectId("58d21667edca14f0f7ffbed9"), "name" : "zhangsan", "age" : 19, "score" : [ 90, 80 ] } { "_id" : ObjectId("58d21667edca14f0f7ffbeda"), "name" : "lisi", "age" : 29, "score" : [ 40, 60 ] }
实例二
插入测试数据
db.test1.insert([ { "id": 1, "results": [ { "product": "abc", "score": 10 }, { "product": "xyz", "score": 5 } ] }, { "id": 2, "results": [ { "product": "abc", "score": 8 }, { "product": "xyz", "score": 7 } ] }, { "id": 3, "results": [ { "product": "abc", "score": 7 }, { "product": "xyz", "score": 8 } ] } ])
定位
其中的一条
> db.test1.find({"results": {"$elemMatch": {"product": "abc", "score": {"$gt": 8}}}}) { "_id" : ObjectId("58d26383fc8d60106f1885bc"), "id" : 1, "results" : [ { "product" : "abc", "score" : 10 }, { "product" : "xyz", "score" : 5 } ] } >
更多关于update与$elemMatch操作
3.3 $size: 匹配数组中元素的个数.
筛选score
拥有三个子集的数据
> db.users.find({"score": {"$size": 3}}) { "_id" : ObjectId("58d21667edca14f0f7ffbedb"), "name" : "xiaoming", "age" : 18, "score" : [ 20, 40, 100 ] }
第四部分 基本操作符
插入测试数据
> for(var i = 0; i < 100; i++){ db.test2.insert({"age": i}) } WriteResult({ "nInserted" : 1 }) > db.test2.find().count()100
4.1 Skip()
语法
>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
官方实例
function printStudents(pageNumber, nPerPage) { print("Page: " + pageNumber); db.students.find().skip(pageNumber > 0 ? ((pageNumber-1)*nPerPage) : 0).limit(nPerPage).forEach( function(student) { print(student.name + "<p>"); } ); }
> db.test2.find().skip(95) { "_id" : ObjectId("58d26dc1b527dc1a130563a8"), "age" : 95 } { "_id" : ObjectId("58d26dc1b527dc1a130563a9"), "age" : 96 } { "_id" : ObjectId("58d26dc1b527dc1a130563aa"), "age" : 97 } { "_id" : ObjectId("58d26dc1b527dc1a130563ab"), "age" : 98 } { "_id" : ObjectId("58d26dc1b527dc1a130563ac"), "age" : 99 }
4.2 排序sort()
默认为升序[1], 降序为[-1]
>db.COLLECTION_NAME.find().sort({KEY:1}) >
例子
#默认升序> db.test2.find().sort({"age": 1}) { "_id" : ObjectId("58d26dc1b527dc1a13056349"), "age" : 0 } { "_id" : ObjectId("58d26dc1b527dc1a1305634a"), "age" : 1 } { "_id" : ObjectId("58d26dc1b527dc1a1305634b"), "age" : 2 } { "_id" : ObjectId("58d26dc1b527dc1a1305634c"), "age" : 3 } { "_id" : ObjectId("58d26dc1b527dc1a1305634d"), "age" : 4 }#降序> db.test2.find().sort({"age": -1}) { "_id" : ObjectId("58d26dc1b527dc1a130563ac"), "age" : 99 } { "_id" : ObjectId("58d26dc1b527dc1a130563ab"), "age" : 98 } { "_id" : ObjectId("58d26dc1b527dc1a130563aa"), "age" : 97 } { "_id" : ObjectId("58d26dc1b527dc1a130563a9"), "age" : 96 }
4.2 排序limit()
>db.COLLECTION_NAME.find().limit(NUMBER)
> db.test2.find().limit(5) { "_id" : ObjectId("58d26dc1b527dc1a13056349"), "age" : 0 } { "_id" : ObjectId("58d26dc1b527dc1a1305634a"), "age" : 1 } { "_id" : ObjectId("58d26dc1b527dc1a1305634b"), "age" : 2 } { "_id" : ObjectId("58d26dc1b527dc1a1305634c"), "age" : 3 } { "_id" : ObjectId("58d26dc1b527dc1a1305634d"), "age" : 4 }
4.3 综上一块来个实例
放在一块说会好些, 要不没有说明性
跳过前10条, 显示接下来的5条, 并按照age升序排列
> db.test2.find().skip(10).sort({"age": 1}).limit(5) { "_id" : ObjectId("58d26dc1b527dc1a13056353"), "age" : 10 } { "_id" : ObjectId("58d26dc1b527dc1a13056354"), "age" : 11 } { "_id" : ObjectId("58d26dc1b527dc1a13056355"), "age" : 12 } { "_id" : ObjectId("58d26dc1b527dc1a13056356"), "age" : 13 } { "_id" : ObjectId("58d26dc1b527dc1a13056357"), "age" : 14 }