0

I have a use case where the database is modelled like this:

name: XYZ
gradeCards: [{
  id: 1234, // id of the report card
  comments: ['GOOD','NICE','WOW']
}, {
  id: 2345,
  comments: ['GOOD','NICE TRY']
}]

Now, I have a query that I would like to query the schema as follows:

I would be given a list of ids and values. For example: the given list is as follows:

[{
  id: 1234,
  comments: ['GOOD','NICE']
},{
  id: 2345,
  comments: ['GOOD']
}]

In short the ID should be matching and the comments should be a sub-array of the comments array for that id and also, all the conditions specified in the array should be matched, so it should be an AND condition on all the conditions provided.

I was able to get to this query, but it matches all of the elements in the comments array, I want that id should be exactly matched and comments should be a subarray.

For matching all elements in comments array:

db.getCollection('user').find({arr:{
    $all: [{
        id:1234,
        comments:['GOOD','NICE','WOW']
    },{
        id:2345,
        comments:['GOOD','NICE TRY']
    }]
 }})

1 Answer 1

2

You can try $all with $elemMatch to match on the query conditions.

db.collection.find({
    gradeCards: {
        $all: [{
            "$elemMatch": {
                id: 1234,
                comments: {
                    $in: ['GOOD', 'NICE']
                }
            }
        }, {
            "$elemMatch": {
                id: 2345,
                comments: {
                    $in: ['GOOD']
                }
            }
        }, ]
    }
})
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the answer, can you please explain why we require $elemMatch? I get the use of $in.
You are welcome. $elemMatch matches on atleast one document in the array which has both id and comments matching query values and $all with $elemMatch to match both the documents on their respective query criteria. More here docs.mongodb.com/manual/reference/operator/query/elemMatch
I got it now. Thanks for the help
Can you provide some idea on if we want an OR condition instead of AND condition of all the specified array inputs? Why doesn't simply replacing $all with $in and removing $elemMatch not work?
You have to use the db.collection.find({ "gradeCards": { "$elemMatch": { "$or": [ { id: 1234, comments: {$in:['GOOD','NICE'] }}, { id: 2345, comments: {$in:['BAD']}} ] } } }) for OR. You are expecting operators to work in certain way which they necessarily may not. Please read about them.

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.