1

Given this:

{ _id: 1, results: [ {a: 82, b: 81}, {a: 82, b: 88} ] }
{ _id: 2, results: [ {a: 82, b: 90}, {a: 82, b: 33} ] }

I want to find the docs which have no results with a or b less than 80. (doc 1 in this case) I know I could use $elemMatch to find the docs with any result containing an a or b less than 80. Is there a way to do the reverse?

Alternatively, I could rewrite my conditions to find docs where all results have a and b greater than 79. Is there an operator which does that?

2 Answers 2

2

Use $not and $or:

db.test.find({ "results" : { 
    "$not" : { 
        "$elemMatch" : { 
            "$or" : [
                { "a" : { "$lt" : 80 } }, 
                { "b" : { "$lt" : 80 } } 
             ]
         } 
     } 
} })

The negation of your condition is "documents with some result having a or b values less than 80". I wrote a query for that, and negated it. Given the way queries work on array elements, I believe it is generally necessary to use $not to enforce a condition on every array element.

Sign up to request clarification or add additional context in comments.

Comments

0

Yes, the opposite of $lt is $gt, which returns all documents that have a certain attribute greater than the specified value.

db.collection.find({results: {$elemMatch: { $and: [{a: {$gt: 79}}, {b: {$gt: 79}}]}}});

EDIT: I have further investigated and it appears that $elemMatch only checks the first element of the array. I have also checked the solution provided by wdberkeley and it works just as intended. Apart from the query built by wdberkeley, the only alternative would be to use the aggregation framework, but that would be far more complex than a simple find query.

2 Comments

Wouldn't that find docs with at least one matching result? I need the docs where all results match.
@jeem My bad. I will further look into it and update the query with a valid solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.