[SERVER-478] Advanced $size quering Created: 11/Dec/09  Updated: 06/Dec/22  Resolved: 16/Jan/18

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: None
Fix Version/s: 3.6.0

Type: New Feature Priority: Minor - P4
Reporter: Valentin Assignee: Backlog - Query Team (Inactive)
Resolution: Done Votes: 77
Labels: neweng
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by SERVER-7884 The length of arrays should be expose... Closed
is duplicated by SERVER-9712 Is it possible to get array size retu... Closed
Related
related to SERVER-589 query $operators should be composable Backlog
Assigned Teams:
Query
Backwards Compatibility: Fully Compatible
Participants:

 Description   

Now we can query only by "array.$size == N" : { array :

{ $size : 123 }

}

It can be useful to query by "array.$size > N", etc.
Something like
{ array : { $size :

{ $gt : 123 }

} }
{ array : { $size :

{ $in : [ 5, 6 ] }

} }



 Comments   
Comment by Asya Kamsky [ 08/Dec/17 ]

Closing this as there are now two ways to query based on size of array operators other than equality.

Comment by Asya Kamsky [ 07/Dec/17 ]

As of 3.6.0 you can now use aggregation $size expression in find via new $expr.

// { array : { $size :{ $gt : 123 }
db.coll.find({$expr:{$gt:[{$size:"$a"},3]}}
// { array : {$size: {$in: [ 5,6]}}
db.coll.find($expr:{$in:[{$size:"$a"},[5,6]]}})

Since aggregation $size will error on non-array "a", if it's possible that a is missing or is not an array you can do:

db.coll.find({a:{$type:"array"},$expr:{$in:[{$size:"$a"},[5,6]]}})
// or alternatively
db.coll..find({$expr:{$in:[{$size:{$ifNull:["$a",[]]}},[5,6]]}})

Comment by Asya Kamsky [ 27/Apr/17 ]

The following query expression is equivalent of "array Xx size is equal or greater than N":

 { "X.N":{$exists:true}} 

So to pull from array as long as at least one element would remain, the update would be:

db.products.update({_id: 1, "priceOptions.1": {$exists: true}}, {$pop:{ priceOptions: 1 }});

Comment by Asya Kamsky [ 14/Jan/15 ]

It's possible to use aggregation framework $size projection operator to satisfy some of the use cases mentioned (but as a workaround, as it would not be as efficient or as flexible).

http://docs.mongodb.org/manual/reference/operator/aggregation/size/

Comment by lukas [ 19/Dec/14 ]

+1

Comment by Dmitry Maevsky [ 06/Oct/13 ]

I am surprised this issue is still open, and ranked so low. There is a workaround for arrays where you $push elements (to keep a separate counter in the document), but even in this case it is not obvious: when you $pull an element you have to be sure it existed in the array in order to decrement the counter. And in case you $addToSet the elements into your array, this feature really becomes crucial, because you cannot always add {$ne: {array: element}} to your query, e.g. if you want to do findAndModify

Comment by Wojciech Fiderek [ 12/Jun/13 ]

Digging out topic.

Yes, it would be usefull in some situations

Comment by Eugene Mirkin [ 22/May/13 ]

Guys, can this be please implemented? I bend over backwards when expressing simple filtering conditions

Comment by Raman Gupta [ 04/Jan/13 ]

@Yuri Finkelstein – the size of the array is already available and/or calculated by MongoDB for the simple $size query. So efficiency isn't an obvious concern in supporting $gt, $lt, and $in on top of $size.

Comment by Yuri Finkelstein [ 09/Dec/12 ]

Just a side comment that implementation has to be efficient. The size of the array has to be a variable atomically maintained and modified when the array grows or shrinks. Counting the number of elements at query time is not a good idea.

Comment by Tjad Clark [ 02/Aug/11 ]

Hmmm, was hoping that this task could get bumped up on the list please ?

I am thinking that this shouldn't be such a great task :-/

I am looking at diving into the MongoDB code to take a look and perhaps supply a patch :? - How difficult is it to have patches accepted :? Or perhaps you could shed some light as to why this hasn't even been scheduled yet :? 1.9 overflowing is just a bit vague .. as mentioned, this doesn't seem like an extremely difficult task (by assumption).

Comment by Eliot Horowitz (Inactive) [ 23/May/11 ]

@nathan, no, sorry. 1.9 is overflowing

Comment by Nathan Ehresman [ 23/May/11 ]

Any chance of this making it into 1.9?

Comment by Ed Rooth [ 08/Dec/10 ]

Would also like to simply return the length of an array.

Comment by Daniel Wood [ 06/Aug/10 ]

We could also use it to atomically prevent numbers from going below 0.. say for example you have:

{
_id: 1,
name: 'MongoDB T-Shirt',
type: 'shirt',
priceOptions: [

{ name: 'Medium', value: 5 }

]
}

You might want to have any number of priceOptions, as long as its more than 0. When removing a priceOption, you need to make sure there is at least one left. An obvious choice here is to do something like:

db.products.update({_id: 1, priceOptions: {$size: {$gt: 1}}},

{priceOptions.pull ....}

);

Comment by Jim Plush [ 20/May/10 ]

This feature is definitely needed for maintaining fixed sized stacks.

Generated at Thu Feb 08 02:54:15 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.