Reputation: 15107
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?
Upvotes: 6
Views: 5128
Reputation: 552
Another way to do this is to use the .nin
(Not IN) form of the query:
Mongoid::Criteria.new(Question).where(:related_question_ids.nin => [nil,[]])
This will only return a Question where the related_question_ids is no nil and not an empty array.
Conversely, you can define :related_question_ids
to have a default value (:default => []
) and then you only need to query for .ne
(Not Equal), like so:
Mongoid::Criteria.new(Question).where(:related_question_ids.ne => [])
Either should work.
Upvotes: 3
Reputation: 1159
This query search if exists any object in the related_question_ids[0] field
Using js shell
db.questions.find("related_question_ids.0": {exists => true} )
Using mongoid
Mongoid::Criteria.new(Question).where(:"related_question_ids.0".exists => true)
You can search greater any size
Mongoid::Criteria.new(Question).where(:"related_question_ids.3".exists =>true)
This solve your problem
Upvotes: 4
Reputation: 6922
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.
Upvotes: 2