Подтвердить что ты не робот

Найти идентификатор последнего вложенного в mongoose вложенного документа

У меня есть модельная схема как:

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

затем

    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"

то

    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
    });

Итак, мой вопрос заключается в том, как найти идентификатор поддокумента, просто вдвинутого в одно поле модели.

4b9b3361

Ответ 1

Я тоже искал этот ответ, и я не уверен, что мне нравится доступ к последнему документу массива. Однако у меня есть альтернативное решение. Метод m['b'].push вернет целое число 1 или 0 - я предполагаю, что это основано на успехе толчка (с точки зрения проверки). Однако, чтобы получить доступ к поддокументу и, в частности, _id вложенного документа, сначала следует использовать метод create, а затем push.

Код выглядит следующим образом:

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); });

Что происходит, когда вы передаете объект методу push или create, приведение Schema происходит немедленно (включая такие вещи, как валидация и кастинг) - это означает, что это время создания ObjectId; не тогда, когда модель сохраняется в Монго. Фактически, mongo автоматически не присваивает значениям _id для поддокументов, это функция мангуста. Mongoose create документируется здесь: создавать документы

Вы также должны отметить, что даже если у вас есть поддокумент _id - он еще не находится в Монго, пока вы его не сохраните, поэтому будьте утомлены любым действием DOCRef, которое вы можете предпринять.

Ответ 2

Mongoose автоматически создаст _id для каждого нового вспомогательного документа, но, насколько мне известно, не возвращает его при его сохранении.

Итак, вам нужно получить его вручную. Метод save возвращает сохраненный документ, включая поддоны. Когда вы используете push, вы знаете, что это будет последний элемент в массиве, поэтому вы можете получить к нему доступ оттуда.

Что-то вроде этого должно сделать трюк.

m['b'].push({ba:235,bb:"World"});
m.save(function(err,model){
  // model.b is the array of sub documents
  console.log(model.b[model.b.length-1].id);
});

Ответ 3

Вопрос "немного" старый, но то, что я делаю в подобной ситуации, генерирует идентификатор поддокумента, прежде чем вставлять его.

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);
});

Таким образом, даже если между сохранением и обратным вызовом существуют другие операции с базой данных, это не повлияет на уже созданный идентификатор.

Ответ 4

Если у вас есть отдельная схема для вашего поддокумента, вы можете создать новый поддокумент модели, прежде чем нажимать на свой родительский документ, и у него будет ID:

var bSchema = new mongoose.Schema({
  ba: Integer,
  bb: String
};

var a = new mongoose.Schema({
  a: String,
  b : [ bSchema ]
});

var bModel = mongoose.model('b', bSchema);
var subdoc = new bModel({
  ba: 5,
  bb: "hello"
});

console.log(subdoc._id);    // Voila!

Позже вы можете добавить его в родительский документ:

m['b'].push(subdoc)
m.save(...