0

How to do search using elemMatch on array of SubDocument? I have document called ReportCollection with elements such as:-

/* 0 */
{
    "_id" : ObjectId("5507bfc435e9470c9aaaa2ac"),
    "owner" : ObjectId("5507bfc31e14d78e177ceebd"),
    "reports" : {
        "xReport" : [ 
            {
                "name" : "xReport",
                "parameters" : {
                    "x" : {
                        "dateTime" : "2015-03-11T18:30:00.000Z",
                        "unit" : 1,
                        "value" : 102
                    }
                },
                "createdBy" : ObjectId("5507bfc31e14d78e177ceebd"),
                "modifiedBy" : ObjectId("5507bfc31e14d78e177ceebd"),
                "_id" : ObjectId("5507bfc41e14d78e177ceebf")
            }
        ]
    }
}

I got reports.xReport[]._id as search parameter.

My following attempt is failing :-

  db.reports.find ({ {owner: ObjectId("5507afd3d54bae3513c185cb")}, 
    { 'reports.xReport': {$elemMatch: {_id: ObjectId("5507afd3d54bae3513c185cd") }}} } )
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
Anand
  • 4,523
  • 10
  • 47
  • 72

1 Answers1

4

It seems like you are trying to put work into the "projection" that you should be doing in the query. Rather your statement should look more like this:

db.reports.find(
    {
        "owner": ObjectId("5507bfc31e14d78e177ceebd"),
        "reports.xReport._id": ObjectId("5507bfc41e14d78e177ceebf")
    },
    { "reports.xReport.$": 1 }
)

So the "query" does the work of matching the array position and the "projection" just uses that position in the match.

Also note that you never really need $elemMatch with a single field to match against. Only when multiple fields are required in the condition do you need to use this to match a specific "element".

By the same token, that should also be in the "query" statement instead.

$elemMatch in it's projected form cannot be used with sub-document fields through dotted notation.

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
  • 1
    Thank You Niel, (Actually whole parameter in my example was part of query, but I made it too complicated, as I you rightly suggested, I didn't need $elemMatch. – Anand Mar 17 '15 at 08:30
  • @SutikshanDubey I usually feel it to be something worth mentioning where the context allows as it is a common misconception along with various other operators ( notably `$in`, `$nin` etc ) that you need to use such an operator when dealing with an array in data. It's not just for your benefit, but at a Q&A resource site, for the benefit of all who may stumble upon the same question. Friendly reminder to accept the answers that solve your questions. Your account is notably "light" on accepted answers to your questions. – Neil Lunn Mar 17 '15 at 08:35
  • hey, I did mark it accepted, not sure, why SO didn't mark the answer as accepted. (may be I had this page opened in two browser window...). I tried again, I hope it will remain accepted. Thanks mate (I also reviewed my other question after ur 1st comment :) ). – Anand Mar 17 '15 at 11:52