MongoDB查询基于嵌入文档的计数

时间:2011-01-16 11:25:53

标签: filter mongodb count

假设我有:

Order: {_id: ..., items: [...]}

如何过滤商品编号大于5的订单?

4 个答案:

答案 0 :(得分:6)

您无法根据嵌入集合的大小进行查询,您需要为此类需求创建具有集合大小的字段(mongo db文档):

  

$ size运算符匹配任何数组   具有指定数量的元素。   以下示例将匹配   object {a:[“foo”]},因为那个数组   只有一个要素:

     

db.things.find({a:{$ size:1}}   );

     

您不能使用$ size来查找范围   大小(例如:带有的数组)   超过1个元素)。如果你需要   查询范围,创建一个额外的   你增加的大小字段   添加元素。

答案 1 :(得分:5)

您可以使用$ where运算符。

> db.orders.save({Order: {items: [1,2]}})                                                    
> db.orders.save({Order: {items: [1,2,3]}})
> db.orders.find({$where:function() { if (this["Order"]["items"].length > 2) return true; }})
{ "_id" : ObjectId("4d334c9102bcfe450ce52585"), "Order" : { "items" : [ 1, 2, 3 ] } }

$ where的两个缺点是它不能使用索引,并且必须将BSON对象转换为JavaScript对象,因为您正在集合中的每个文档上运行自定义JavaScript函数。

所以,对于大型集合来说,$ where可能非常慢。但是,对于临时或很少运行的查询,它非常方便。如果您经常需要运行这样的查询,那么您应该遵循Bugai13的建议,因为您可以索引存储数组大小的密钥。

答案 2 :(得分:2)

我也面临这种困境。不确定为什么默认情况下它不存在于MongoDB中。最有效的方法是还存储一个名为countlength的属性或表示数组中有多少项的内容。

然后,您可以索引该属性并对其进行范围查询。它会使您的查询简单快捷。

只需确保您的应用程序保持同步。

答案 3 :(得分:0)

要查看长度是否大于5,可以测试是否存在第6个元素:

db.orders.find({"items.6": {$exists: true}})

这比使用$where更为有效。