Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/426.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将对象推送到现有集合后,检索该对象的自生成_id值_Javascript_Node.js_Mongodb_Mongoose - Fatal编程技术网

Javascript 将对象推送到现有集合后,检索该对象的自生成_id值

Javascript 将对象推送到现有集合后,检索该对象的自生成_id值,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,我有一个mongodb文档,比如说有一个模式 class: String, class_teacher: String, students: [ { student: String, marks: number } ] 在上面的示例中,如果我将一个新学员推送到集合中,它将为每个学员生成一个\u id,我将使用整个文档的更新查询来完成此操作 这样做对吗 如果是,如何在推送学生对象后立即获取每个学生的_id 一段时间后,如果我想更新一个学生的分数,最好

我有一个mongodb文档,比如说有一个模式

class: String,
class_teacher: String,
students: [
    { 
       student: String,
       marks: number
    }
]
在上面的示例中,如果我将一个新学员推送到集合中,它将为每个学员生成一个
\u id
,我将使用整个文档的更新查询来完成此操作

  • 这样做对吗

  • 如果是,如何在推送学生对象后立即获取每个学生的_id

  • 一段时间后,如果我想更新一个学生的分数,最好的方法是什么


  • 在nice模式下,我将回答您的所有“问题”,下面是一些演示代码:

    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()
    提取,然后您可以获得最后一个
    \u 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()
    方法以及“多”选项

    您还可以使用运算符将新学员“添加”到数组中,就像使用所示方法返回文档之前一样,因此您也可以通过以下方式应用获取新的
    \u 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()
    。但是,这些是替代方法,通常比处理整个文档产生的“网络流量”要少。

    如果你一次只问一个问题,效果最好。+1对于这些努力,我正在从你的回答中学习(实际上很享受)猫鼬:)谢谢。。它非常详细,信息丰富。