Kamilski81 Kamilski81 - 6 months ago 37
Ruby Question

How do I query for item with non-empty array with mongoid?

I have the following code that works as expected:

Mongoid::Criteria.new(Question).where(:related_question_ids.size => 0)


However, I would like to perform the query to return questions with related_questions array greater than 0. For example,

Mongoid::Criteria.new(Question).where(:related_question_ids.size.gte => 0)


Is there a way to do this with mongoid or mongodb?

Answer

You can use the $size operator to query by array sizes. Consider the following example using the JS shell:

> db.foo.drop()
> db.foo.insert({_id: 1, x:[1,2]});
> db.foo.insert({_id: 2, x:[]});
> db.foo.insert({_id: 3, x:3});

> db.foo.find({x: {$size: 0}})
{ "_id" : 2, "x" : [ ] }

> db.foo.find({x: {$size: 1}})

> db.foo.find({x: {$size: 2}})
{ "_id" : 1, "x" : [ 1, 2 ] }

> db.foo.find({x: {$not: {$size: 2}}})
{ "_id" : 2, "x" : [ ] }
{ "_id" : 3, "x" : 3 }

> db.foo.find({x: {$not: {$size: 0}}})
{ "_id" : 1, "x" : [ 1, 2 ] }
{ "_id" : 3, "x" : 3 }

I'm not familiar with Mongoid, but I found an example using $size in this documentation.

Two caveats with $size are that it cannot utilize an index (other parts of the query certainly can) and it cannot be used in range queries. If you don't mind the additional bookkeeping, a viable option is to store the array's size in a separate field (likely indexed) and query on that any way you like.

Comments