14

Given a collection like this:..

[ { "_id" : ObjectId("5546329a470000850084a621"), "name": "Joe", "surname": "Smith", "accounts": [ { "_id" : ObjectId("5546329a470000850084a655"), "default": true, "status" : "approved", "activationTime" : ISODate("2013-05-03T14:37:15.025Z") }, { "_id" : ObjectId("5546329a470000850084a688"), "default": true, "status" : "approved", "activationTime" : ISODate("2014-06-03T14:37:15.025Z") } ] }, { "_id" : ObjectId("9546329a470079850084a622"), "name": "Jimmy", "surname": "Brown", "accounts": [ { "_id" : ObjectId("5546329a470790850084a651"), "default": true, "status" : "suspended", "activationTime" : ISODate("2015-02-03T14:37:15.025Z") }, { "_id" : ObjectId("5546329a470019850084a611"), "default": true, "status" : "approved", "activationTime" : ISODate("2015-04-03T14:37:15.025Z") } ] }, ] 

... how do I find a document by accounts.N._id? I've tried this...

db.users.find( {}, { "accounts": 0, "accounts": { "$elemMatch": { "_id" : ObjectId("5546329a470019850084a611"), "default": true } } } ) 

... but it does't work since I get only the _id of all the documents:

{ "_id" : ObjectId("5546329a470000850084a621") } { "_id" : ObjectId("9546329a470079850084a622") } 

Am I missing something?

EDIT

The result that I actually need is something like this:

{ "_id" : ObjectId("9546329a470079850084a622"), "name": "Jimmy", "surname": "Brown" } 

For instance, I need to find by accounts.N._id but without showing the nested document itself.

1
  • is there any way to update status of Same object? Commented Jun 3, 2021 at 13:59

3 Answers 3

33

Use dot notation:

When the field holds an embedded document, a query can either specify an exact match on the embedded document or specify a match by individual fields in the embedded document using the dot notation.

db.coll.find({ "accounts._id" :ObjectId("5546329a470019850084a611") }) 

If you need to output only the part of an array where you have your _id you need to use dollar in projection

The positional $ operator limits the contents of an from the query results to contain only the first element matching the query document.

and your query would look like:

db.coll.find({ "accounts._id" :ObjectId("5546329a470019850084a611") }, { "accounts.$.": 1 }) 

P.S. if you need the output like in your modified questions, use this:

db.coll.find({ "accounts._id" :ObjectId("5546329a470019850084a611") }, { accounts : 0 }) 
Sign up to request clarification or add additional context in comments.

1 Comment

Maybe it helps someone: to cast the id string to ObjectId, one must import const objectID = require("mongodb").ObjectID
7

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

In your case:

db.users.find({'_id': ObjectId('5546329a470000850084a621')}, {accounts: {$elemMatch: {_id: ObjectId('5546329a470000850084a655')}}}) 

Refer: Mongo Docs

1 Comment

It includes example with description and links to that referred page and glossary. So, that person who asked this question can see other MongoDB terminologies.
2

Use $elemMatch in criteria and use $ positional operator in project as below :

db.users.find({ "accounts": { "$elemMatch": { "_id": ObjectId("5546329a470019850084a611"), "default": true } } }, { "accounts.$._id": 1 // "accounts.$": 1 also works }).pretty() 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.