2013-09-12 3 views
13

У меня есть модель схемы, как:находка идентификатор последней поддокументе вставляется в мангуста

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

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

ответ

7

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

это действительно единственный способ? – kumikoda

+7

Проблемы с синхронизацией с асинхронными вызовами базы данных могут сделать это плохой идеей. – bbengfort

24

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

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

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

+0

Мне было бы хорошо, если бы у мангуста было атомное решение, которое не включало получение последнего элемента. :( – FRD

+0

Отличный ответ, спасибо! – Neta

2

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

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

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

0

Если у вас есть отдельная схема для вашего поддокументе, то вы можете создать новый поддокумент от модели перед ее на свой родительский документ, и он будет иметь 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(... 
Смежные вопросы