0
{
    "_id" : "R9zbu8oTWwgxT5eCR",
    "practiceSetup" : {
        "operatoriesSettings" : [ 
            {
                "name" : "Operatory 1",
                "description" : "Room 1",
                "status" : true
            },
                            {
                "name" : "Operatory 2",
                "description" : "Room B",
                "status" : true
            }
        ],  

}

I'm trying to lookup object that has name "Operatory 1" and only return that object.

Here is what I have tried,

Practice.findOne({ _id: 'R9zbu8oTWwgxT5eCR' }, { "$elemMatch": { "practiceSetup.operatoriesSettings": { "name": "Operatory 1" } } } );

However this will return the whole document, not that particular object, not sure what I'm doing wrong here.

Deano
  • 11,582
  • 18
  • 69
  • 119
  • I think I just answered a very similar question: https://stackoverflow.com/questions/47624171/getting-subdocument-from-document/47624861#47624861 – Buzz Moschetti Dec 04 '17 at 06:14

3 Answers3

0

You can try out this,

Practice.findOne({ _id: 'R9zbu8oTWwgxT5eCR' }).map(function(u){
        return u.practiceSetup
                .operatoriesSettings
                .filter( m => m.name == "Operatory 1");
    })

This will return:

[
 [ 
    {
        "name" : "Operatory 1",
        "description" : "Room 1",
        "status" : true
    }
 ]
]
Anirudh Bagri
  • 2,346
  • 1
  • 21
  • 33
0

That's how $elemMatch projection works:

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

If you only need that specific subdocument, you get it using JS:

const doc = Practice.findOne(
  { _id: 'R9zbu8oTWwgxT5eCR' },
  {
    $elemMatch: {
      'practiceSetup.operatoriesSettings': {
        name: 'Operatory 1'
      }
    }
  }
);

const operator1 = doc.practiceSetup.operatoriesSettings[0];
Ramil Muratov
  • 548
  • 5
  • 13
0

I found that using "Projections" will return matched object off an array.

Query:

{ "_id": "R9zbu8oTWwgxT5eCR", "practiceSetup.operatoriesSettings": { $elemMatch: {'name': 'Operatory 1'} } }

Projection

{"practiceSetup.operatoriesSettings.$.name": 1}

Full Query:

db.Practice.findOne({ 
    "_id" : "R9zbu8oTWwgxT5eCR", 
    "practiceSetup.operatoriesSettings" : {
        "$elemMatch" : {
            "name" : "Operatory 1"
        }
    }
}, { 
    "practiceSetup.operatoriesSettings.$.name" : 1.0
});

Returns

{ 
    "_id" : "R9zbu8oTWwgxT5eCR", 
    "practiceSetup" : {
        "operatoriesSettings" : [
            {
                "name" : "Operatory 1", 
                "description" : "Room 1", 
                "status" : true
            }
        ]
    }
}

Meteor

When using Meteor methods, you will need to use "fields" when using Projections.

   return Practice.findOne({
        "_id": "R9zbu8oTWwgxT5eCR",
        "practiceSetup.operatoriesSettings": {
          "$elemMatch": {
            "name": data
          }
        }
      }, 
        { fields: { 'practiceSetup.operatoriesSettings.$.name': 1, _id: 0 } }
       );
Deano
  • 11,582
  • 18
  • 69
  • 119