[英]Retrieve the self-generated _id value of the object after pushing it to a existing collection
我有一個mongodb文件,假設有架構
class: String,
class_teacher: String,
students: [
{
student: String,
marks: number
}
]
在上面的示例中,如果我將一個新學生推送到集合中,它將為每個學生生成一個_id
,並且我將通過對整個文檔使用更新查詢來完成此操作。
這是正確的方法嗎?
如果是,當我按下學生對象時,如何獲得每個學生的_id?
一段時間后,如果我想更新一個學生的成績,什么是最好的方法?
在好的模式下,我將回答您所有的“問題”,這是一些演示代碼:
var mongoose = require("mongoose"),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/test');
var classSchema = new Schema({
class: String,
teacher: String,
students: [{ student: String, marks: Number }]
});
var Class = mongoose.model("Class", classSchema);
var myclass = new Class();
myclass.students.push(
{ student: "bill", marks: 10 },
{ student: "ted", marks: 5 }
);
console.log("Whole:\n %s\n",myclass);
console.log("Last added _id: %s\n",myclass.students.slice(-1)[0]._id);
myclass.save(function(err,myclass) {
if (err) throw err;
Class.findOneAndUpdate(
{ "students.student": "ted" },
{ "$set": { "students.$.marks": 7 } },
function(err,doc) {
if (err) throw err;
console.log(doc);
}
);
});
因此總體而言:
即使您可能會發現為“學生”單獨定義架構從長遠來看更易於維護,也可以肯定是沒有問題的:
var studenSchema = new Schema({ student: String, marks: Number }); var classSchema = new Schema({ class: String, teacher: String, students: [studentSchema] });
那么,當您以這種方式修改時,可以使用.slice()
將數組中最后添加的元素.slice()
,然后可以獲取最后的_id
值。
console.log("Last added _id: %s\\n",myclass.students.slice(-1)[0]._id);
最好使用.findOneAndUpdate()
或類似的操作來完成標記的更新。 在這里,您查詢以匹配文檔和數組元素,並使用位置$
運算符更新正確的元素:
Class.findOneAndUpdate( { "students.student": "ted" }, { "$set": { "students.$.marks": 7 } }, function(err,doc) { if (err) throw err; console.log(doc); } );
這還將返回已修改的文檔,以便您可以查看更改。 對於“批量”操作,您可以使用.update()
方法以及“ multi”選項。
您還可以使用$push
運算符將新學生“添加”到數組,就像使用所示方法返回文檔之前一樣,因此您也可以通過這種方式申請獲取新的_id
值:
Class.findOneAndUpdate(
{ "students.student": "ted" },
{ "$push": { "students": { "student": "sally", "marks": 4 }} },
function(err,doc) {
if (err) throw err;
console.log("Whole:\n %s", doc);
console.log("Last added _id: %s\n",doc.students.slice(-1)[0]._id);
}
);
並產生如下結果:
Whole:
{ _id: 53bc9844c1cbd4d24eac8db6,
__v: 0,
students:
[ { student: 'bill', marks: 10, _id: 53bc9844c1cbd4d24eac8db7 },
{ student: 'ted', marks: 7, _id: 53bc9844c1cbd4d24eac8db8 },
{ student: 'sally', marks: 4, _id: 53bca6c346d93b32624e5af4 } ] }
Last added id: 53bca6c346d93b32624e5af4
如果需要其他模式驗證功能或字段值上的其他掛鈎,則需要分別.find()
文檔,在代碼中進行修改,然后在.save()
修改。 但是這些是替代方法,與處理整個文檔相比,它們通常產生的“有線通信量”更少。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.