Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retrieve parent document based on subdocument values in Mongoose?

I have the following schema's:

var Child = new mongoose.Schema({
    'field': String,
    'value': String
  });

var Parent = new mongoose.Schema({
    'name': String,
    'children': [ Child ]
  });

I want to return the Parent for which one of the Child's corresponds to the following JSON object:

{ 'field': 'Family Name', 'value': 'Smith' }

I have tried this:

Parent.findOne({ 'children': { 'field': 'Family Name', 'value': 'Smith' } }, fn ...)

but it keeps on retrieving null.

EDIT:

Testing through the Mongo shell extension, I found out that the Child sub-documents have their own _id's. If I add that _id to the query, it fetches the parent document. Now, I don't know in advance what that child id will be. So: how can I remove it from the sub-document query? (In other words, the above query literally looks for a JSON object with only two properties, while the sub-documents have three)

My environment is: Node.js, Mongoose, MongoDB

like image 439
Ze Jibe Avatar asked Mar 28 '13 15:03

Ze Jibe


People also ask

What is a subdocument in MongoDB?

Subdocuments are documents embedded in other documents. In Mongoose, this means you can nest schemas in other schemas. Mongoose has two distinct notions of subdocuments: arrays of subdocuments and single nested subdocuments.

What is a sub document?

subdocument (plural subdocuments) (computing, wordprocessing) A document making up part of a larger document.

What is select in Mongoose schema?

select() is a method of Mongoose that is used to select document fields that are to be returned in the query result. It is used to include or exclude document fields that are returned from a Mongoose query. The select() method performs what is called query projection.


2 Answers

It seems the $elemMatch is the query operator to solve this problem. The actual query should be written as follows:

Parent.findOne({ 'children': { $elemMatch: { 'field': 'Family Name', 'value': 'Smith' } } }, fn ...)
like image 133
Ze Jibe Avatar answered Oct 17 '22 02:10

Ze Jibe


Is there a reason you use field, value structure on the child documents? It would be easier to simply use the key as the field, like {"FamilyName": "Smith"}. This would allow something like:

Parent.findOne({'children.FamilyName': 'Smith'}, function(err, doc){...});
like image 36
tbeseda Avatar answered Oct 17 '22 03:10

tbeseda