开发者

MongoDB query based on count of embedded document

Suppose I have:

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

How to f开发者_如何学Goilter orders which have item number greater than 5?


You cann't query by size of embed collection, you need to create field with size of collection for such needs(mongo db documentation):

The $size operator matches any array with the specified number of elements. The following example would match the object {a:["foo"]}, since that array has just one element:

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

You cannot use $size to find a range of sizes (for example: arrays with more than 1 element). If you need to query for a range, create an extra size field that you increment when you add elements.


You can use the $where operator.

> 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 ] } }

Two downsides of $where are that it can't use an index and the BSON object must be converted to a JavaScript object, since you are running a custom JavaScript function on every document in the collection.

So, $where can be very slow for large collections. But, for ad hoc or rarely run queries, it's extremely handy. If you frequently need to run queries like this, then you should follow Bugai13's recommendation, since you can then index the key in which you store the array size.


I too faced this dilemma. Not sure why it doesnt exist in MongoDB by default. The most efficient way is to also store a property called count or length or something that denotes how many items are in the array.

Then you can index that property and do range queries on it. It'll keep your queries simple and quick.

Just make sure that your application keeps it in sync.


To see if the length is greater than 5, you can test if a 6th element exists:

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

This is much more efficient than using $where.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜