簡體   English   中英

將對象推送到現有集合后,檢索對象的自生成_id值

[英]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 ,並且我將通過對整個文檔使用更新查詢來完成此操作。

  1. 這是正確的方法嗎?

  2. 如果是,當我按下學生對象時,如何獲得每個學生的_id?

  3. 一段時間后,如果我想更新一個學生的成績,什么是最好的方法?

在好的模式下,我將回答您所有的“問題”,這是一些演示代碼:

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

});

因此總體而言:

  1. 即使您可能會發現為“學生”單獨定義架構從長遠來看更易於維護,也可以肯定是沒有問題的:

     var studenSchema = new Schema({ student: String, marks: Number }); var classSchema = new Schema({ class: String, teacher: String, students: [studentSchema] }); 
  2. 那么,當您以這種方式修改時,可以使用.slice()將數組中最后添加的元素.slice() ,然后可以獲取最后的_id值。

     console.log("Last added _id: %s\\n",myclass.students.slice(-1)[0]._id); 
  3. 最好使用.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM