MongoDB query based on the number of embedded documents

Suppose I have:

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

How to filter orders with a position number greater than 5?

+4
source share
3 answers

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

There are two drawbacks to $, where they cannot use the index, and the BSON object must be converted to a JavaScript object, since you are executing your own JavaScript function for each document in the collection.

So $ where for large collections can be very slow. But for special or rarely executed queries, this is very convenient. If you often need to run such queries, you should follow the Bugai13 recommendation, as you can index the key in which you store the size of the array.

+5
source

You cannot request the size of the built-in collection, you need to create a field with the size of the collection for such needs (mongo db documentation):

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

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

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

+7
source

I also faced this dilemma. I don’t know why it does not exist in MongoDB by default. The most efficient way is to also save a property with the name count or length or something that indicates the number of elements in the array.

Then you can index this property and set range queries on it. It will keep your queries simple and fast.

Just make sure your application syncs it.

+2
source

Source: https://habr.com/ru/post/1201291/


All Articles