null
null的查询稍微有点不同,假如我想查询z为null的数据,如下:
db.collec_1.find({z:null})
这样不仅会查出z为null的文档,也会查出所有不包含z字段的文档。如果只想查询z为null的字段,那就再多加一个条件,判断一下z这个字段是否存在,如下:
db.collec_1.find({z:{$in:[null],$exists:true}})
正则表达式
使用正则表达式查询我们在前面也已经介绍过了,这里的正则表达式语法和JS中的正则表达式语法一致,比如查询所有key为x,value以hello开始且不区分大小写的文档:
db.collec_1.find({x:/^(hello)(.[a-zA-Z0-9])+/i})
数组查询
假设有一个数据集如下:
{ "_id" : ObjectId("619c844395a97c19e2b88aeb"), "books" : [ "三国演义", "红楼梦", "水浒传" ] }
查询books中含有三国演义的文档:
db.books_2.find({books:"三国演义"})
如果要查询既有三国演义又有红楼梦的文档,可以使用$all,如下:
db.books_2.find({books:{$all:["三国演义","红楼梦"]}})
当然我们也可以使用精确匹配,比如查询books为三国演义、红楼梦、水浒传的文档,如下:
db.books_2.find({books:["三国演义","红楼梦","水浒传"]})
不过这种就会一对一精确匹配。
也可以按照下标匹配,比如我想查询数组中下标为2的项为水浒传的文档,如下:
db.books_2.find({"books.2":"水浒传"})
也可以按照数组长度来查询,比如我想查询数组长度为3的文档,如下:
db.books_2.find({books:{$size:3}})
如果想查询数组中的前两条数据,可以使用$slice,如下:
db.books_2.find({},{books:{$slice:2}})
注意这里要写在find第二个参数的位置。2表示数组中前两个元素,-2表示从后往前数两个元素。也可以截取数组中间的元素,比如查询数组中的第二个到第四个元素,如下:
db.books_2.find({},{books:{$slice:[1,3]}})
数组中的与问题也值得说一下,假设有如下数据:
{ "_id" : ObjectId("619c8efc95a97c19e2b88aec"), "x" : [ 5, 25 ] }
我想将数组中vaule取值在(10,20)之间的文档获取到,如下操作:
db.arrays_1.find({x:{$gt:10,$lt:20}})
此时上面这个文档虽然不满足条件,却依然被查找出来了。因为25>10,而5<20。要解决这个问题,我们可以使用$elemMatch,如下:
db.arrays_1.find({x:{$elemMatch:{$gt:10,$lt:20}}})
$elemMatch要求MongoDB同时使用查询条件中的两个语句与数组中的一个元素进行比较。
嵌套文档查询
嵌套文档有两种查询方式,准备数据如下:
{ "_id" : ObjectId("619c947095a97c19e2b88aed"), "x" : 1, "y" : { "z" : 2, "k" : 3 } }
想要查询上面这个文档,查询语句如下:
db.objs_1.find({y:{z:2,k:3}})
但是这种写法要求严格匹配,顺序都不能变,假如写成了
db.objs_1.find({y:{k:3,z:2}})
就匹配不到了,因此这种方法不够灵活。我们一般推荐的是下面这种写法:
db.objs_1.find({"y.z":2,"y.k":3})
这种写法可以任意颠倒顺序。