Sajjad Ahmed
Sajjad Ahmed

Reputation: 367

Extract two sub array values in mongodb by $elemMatch

Aggregate, $unwind and $group is not my solution as they make query very slow, there for I am looking to get my record by db.collection.find() method.

The problem is that I need more then one value from sub array. For example from the following example I want to get the "type" : "exam" and "type" : "quiz" elements.

{
    "_id" : 22,
    "scores" : [
        {
            "type" : "exam",
            "score" : 75.04996547553947
        },
        {
            "type" : "quiz",
            "score" : 10.23046475899236
        },
        {
            "type" : "homework",
            "score" : 96.72520512117761
        },
        {
            "type" : "homework",
            "score" : 6.488940333376703
        }
    ]
}

I am looking something like

db.students.find(
// Search criteria
{ '_id': 22 },

// Projection
{ _id: 1, scores: { $elemMatch: { type: 'exam', type: 'quiz' } }}
)

The result should be like

{ "_id": 22, "scores" : [ { "type" : "exam", "type" : "quiz" } ] }  

But this over ride the type: 'exam' and returns only type: 'quiz'. Have anybody any idea how to do this with db.find()?

Upvotes: 1

Views: 1171

Answers (1)

Neo-coder
Neo-coder

Reputation: 7840

This is not possible directly using find and elemMatch because of following limitation of elemMatch and mongo array fields.

The $elemMatch operator limits the contents of an field from the query results to contain only the first element matching the $elemMatch condition. ref. from $elemMacth

and mongo array field limitations as below

Only one positional $ operator may appear in the projection document.

The query document should only contain a single condition on the array field being projected. Multiple conditions may override each other internally and lead to undefined behavior. ref from mongo array field limitations

So either you tried following this to find out only exam or quiz

db.collectionName.find({"_id":22,"scores":{"$elemMatch":{"type":"exam"}}},{"scores.$.type":1}).pretty()

is shows only exam scores array.

Otherwise you should go through aggregation

Upvotes: 1

Related Questions