Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

find id of latest subdocument inserted in mongoose

i have a model schema as :

var A = new Schema ({
  a: String,
  b : [ { ba: Integer, bb: String } ]
}, { collection: 'a' } );

then

    var M = mongoose.model("a", A);
    var saveid = null;
    var m = new M({a:"Hello"});
    m.save(function(err,model){
       saveid = model.id;
   });  // say m get the id as "1"

then

    m['b'].push({ba:235,bb:"World"});
    m.save(function(err,model){
      console.log(model.id); //this will print 1, that is the id of the main Document only. 
//here i want to find the id of the subdocument i have just created by push
    });

So my question is how to find the id of the subdocument just pushed in one field of the model.

like image 289
codeofnode Avatar asked Sep 12 '13 09:09

codeofnode


People also ask

What is Mongoose subdocument?

In Mongoose, subdocuments are documents that are nested in other documents. You can spot a subdocument when a schema is nested in another schema. Note: MongoDB calls subdocuments embedded documents.

What is Mongoose object ID?

ObjectId . A SchemaType is just a configuration object for Mongoose. An instance of the mongoose. ObjectId SchemaType doesn't actually create MongoDB ObjectIds, it is just a configuration for a path in a schema.

What does findById return Mongoose?

Return value findById returns the document where the _id field matches the specified id . If the document is not found, the function returns null .


2 Answers

I've been looking for this answer as well, and I'm not sure that I like accessing the last document of the array. I do have an alternative solution, however. The method m['b'].push will return an integer, 1 or 0 - I'm assuming that is based off the success of the push (in terms of validation). However, in order to get access to the subdocument, and particularly the _id of the subdocument - you should use the create method first, then push.

The code is as follows:

var subdoc = m['b'].create({ ba: 234, bb: "World" });
m['b'].push(subdoc);
console.log(subdoc._id);
m.save(function(err, model) { console.log(arguments); });

What is happening is that when you pass in the object to either the push or the create method, the Schema cast occurs immediately (including things like validation and type casting) - this means that this is the time that the ObjectId is created; not when the model is saved back to Mongo. In fact, mongo does not automatically assign _id values to subdocuments this is a mongoose feature. Mongoose create is documented here: create docs

You should also note therefore, that even though you have a subdocument _id - it is not yet in Mongo until you save it, so be weary of any DOCRef action that you might take.

like image 133
bbengfort Avatar answered Oct 19 '22 19:10

bbengfort


The question is "a bit" old, but what I do in this kind of situation is generate the subdocument's id before inserting it.

var subDocument = {
    _id: mongoose.Types.ObjectId(),
    ba:235,
    bb:"World"
};

m['b'].push(subDocument);

m.save(function(err,model){
  // I already know the id!
  console.log(subDocument._id);
});

This way, even if there are other database operations between the save and the callback, it won't affect the id already created.

like image 25
outreal Avatar answered Oct 19 '22 17:10

outreal