2014-03-23
本文探索如何在MongoDB下根据数组大小进行查询。笔者使用的mongodb版本为2.4.7。
插入测试数据
db.data.insert({name:'a', num:[12,123,22,34,1]});
db.data.insert({name:'b', num:[42,22]});
db.data.insert({name:'c', num:[49]});
键num
对应的值是数组。
查询num的数组值具有指定大小的document
最好的方法是使用$size
,例如指定大小为2
,可以:
db.data.find({num:{$size:2}})
资料[1]中详细介绍了$size
。不过$size
有一个缺陷,就是无法查询某个范围的大小,例如下面的语句是无法按照预期运行的:
db.data.find({num:{$size:{$gt:2}}}); //错误
资料[1]中建议,如果需要查询的数组大小在某个范围,可以另外为每个文档添加一个键来保存当前数组的大小。
如果数组大小是某个范围
资料[2][3]提供了另外两种思路,第一个思路是使用$where
,例如如果要求数组大小小于3:
db.data.find({ $where: "this.num.length < 3" })
这种方法具有很大的灵活性,但是速度会慢一些。
关于$where
,请参考资料[4]。
另外一个比较高效的方法是判断数组中的某个指定索引的元素是否存在,例如如果要求数组大小小于3:
db.data.find({ "num.2": {$exists:0} })
数组大小小于3,就意味着num[2]
不存在。
如果要求数组大小大于3,可以:
db.data.find({ "num.3": {$exists:1} })
更麻烦的方法
更麻烦的方法一般是更笨的方法,在这里mapreduce和js脚本的方法都有些麻烦。
资料
[1] $size
[2] remove documents with array field's size less than 3 in mongoDB
[3] In MongoDB, how do I find documents where array size is greater than 1?
[4] $where