这篇博客,我们来介绍几种查询的骚操作。
投影(projection)——返回指定的字段
在mongodb的查询中,可以通过一个bson来指定在这个查询里返回的字段。如果不指定,则默认全部返回。bson的格式如下:
{ field1: <value>, field2: <value> ... }
value:
1或者true表示在返回的文档中需要包含的字段
0或者false表示不返回该字段
例:
db.test.find()
结果为:
{ “_id” : ObjectId(“5d11c1dd4a715b97743cfabe”), “name” : “tom”, “age” : 13, “like” : “apple” }
{ “_id” : ObjectId(“5d11cc6f4a715b97743cfabf”), “name” : “tom”, “age” : 14, “like” : “apple” }
{ “_id” : ObjectId(“5d3ee58653166082cbd19439”), “favorite” : { “sport” : “soccer”, “fruit” : [ “apple”, “peach” ] } }
只返回某些字段:
db.test.find({age:13},{name:1,_id:0})
结果为:
{ “name” : “tom” }
排除某些字段:
db.test.find({age:13},{name:0,_id:0})
结果为:
{ “age” : 13, “like” : “apple” }
返回嵌入文档的指定字段
db.test.find({},{"favorite.sport":1,_id:0})
结果为:
{ “favorite” : { “sport” : “soccer” } }
返回嵌入文档的数组
db.test.find({},{"favorite.fruit":1,_id:0})
结果为:
{ “favorite” : { “fruit” : [ “apple”, “peach” ] } }
注:
1:当要返回_id时,不需要显示注明_id:1,查询方法默认都是返回的。当显示注明_id:0时才不会返回。
2:对于一个查询语句,不能同时指定一个属性为1,另一个属性为0(_id是唯一一个可以显示排除的)
null值查询
我们现在数据库中插入两条记录
db.test.insert(
[
{ "x" : 1, "y" : null },
{ "x" : 2 }
]
)
当我们想要查询y:null数据时,可能会使用如下的查询语句:
db.test.find({y:null})
结果为:
{ “_id” : ObjectId(“5d773d6a50b8e96191afdf53”), “x” : 1, “y” : null }
{ “_id” : ObjectId(“5d773d6a50b8e96191afdf54”), “x” : 2 }
我们有没有查询 { “x” : 1, “y” : null }这条记录的方法呢?
答:有。
*第一种方法:*给mongo库加上稀疏索引(只会存储被建立索引的属性有值的文档)。加上以后,我们就只会查询到显示的null值。
*第二种方法:*使用{$type:10}进行类型筛选,也只会匹配出显示指定的null。
如果想要查不存在这个属性的文档也有方法——使用{$exists:false}进行属性存在性筛选。
find的数值大小比较
操作 | 格式 | 示例 |
---|---|---|
等于 | {key:value} | db.test.find({name:“tom”}) |
小于 | {key:{$lt:value}} | db.test.find({age:{$lt:14}}) |
小于等于 | {key:{$lte:value}} | db.test.find({age:{$lt:13}}) |
大于 | {key:{$gt:value}} | db.test.find({age:{$gt:13}}) |
大于等于 | {key:{$gte:value}} | db.test.find({age:{$gte:14}}) |
不等于 | {key:{$ne:value}} | db.test.find({age:{$ne:13}}) |
大于一个数且小于另一个数 | {key:{$gt:value1,$lt:value2}} | db.test.find({age:{$gt:13,$lt:15}}) |
大于一个数或者小于另一个数 | {$or:[{key:{$gt:value1}},{key:{$lt:value2}}]} | db.test.find({$or:[{age:{$gt:15}},{age:{$lt:14}}]}) |
大于一个数或者等于另一个数 | {$or:[{key:{$gt:value1}},{key:value2}]} | db.test.find({$or:[{age:{$gt:15}},{age:14}]}) |
注:上面的操作中 大家要尤其注意大于一个数且小于另一个数的写法,如果写成{key:{$gt:value1},{key:{$lt:value2}}
则意义就会不一样了。大家可以自己去试一下
游标
mongo的find方法会返回一个cursor游标。
如果没有把这个游标赋值给变量,则游标会自动在shell中迭代20次(打印出find结果的前20行);
当通过var把游标赋值给一个变量后,在shell命令行则不会进行默认迭代
如:
var result = db.test.find();
当我们需要在命令行输出查询结果的时候,输入result则游标会向下迭代20次(即打印20次结果),当输入result.next()
时,游标会迭代一次(即打印1次结果)
limit,skip,sort
顾名思义,limit(n)是指定查询结果返回的记录数,skip(n)是跳过指定数量的结果,sort({key:options})表示按照一定顺序排序。
sort({key:1}):表示对key字段升序排序,
sort({key:0}):表示对key字段降序排序
limit和skip可以实现小数据量的分页,如果数据量太大就不适用skip方法,因为skip方法是一条一条数过去的。数据量大的时候,可以利用某些字段有序的性质,使用find来代替sort进行分页,效率会大大提高。
比如我们在文档结构上面增加了逻辑上的自增值:
我们就可以使用$gt,limit组合来代替sort,skip,limit组合了。
注:skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit()。
我们由此可以看出$操作符非常的强大。我们将会在之后专门用1~2篇幅来讲$操作符。