找到插入mongoose的最新子文档的id

cod*_*ode 16 mongoose mongodb node.js

我有一个模型架构:

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

然后

    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"
Run Code Online (Sandbox Code Playgroud)

然后

    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
    });
Run Code Online (Sandbox Code Playgroud)

所以我的问题是如何找到刚推入模型的一个字段的子文档的id.

bbe*_*ort 30

我一直在寻找这个答案,我不确定我是否喜欢访问数组的最后一个文档.不过,我确实有另一种解决方案.该方法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); });
Run Code Online (Sandbox Code Playgroud)

发生的事情是,当您将对象传递给push或create方法时,Schema强制转换立即发生(包括验证和类型转换等) - 这意味着这是创建ObjectId的时间; 不是当模型保存回Mongo时.实际上,mongo不会自动将_id值分配给子文档,这是一个猫鼬功能.这里记录了Mongoose创建:创建文档

因此,您还应该注意,即使您有一个子文档_id - 在您保存之前它还没有在Mongo中,所以要对您可能采取的任何DOCRef操作感到厌倦.


Sim*_*mes 7

Mongoose会自动为每个新的子文档创建一个_id,但是 - 据我所知 - 当你保存它时不会返回它.

所以你需要手动获取它.该save方法将返回保存的文档,包括subdocs.在您使用时,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);
});
Run Code Online (Sandbox Code Playgroud)

  • 异步数据库调用的时序问题可能会让这个想法变得糟糕. (8认同)
  • 这真的是唯一的方法吗? (6认同)

小智 6

问题是“有点”古老的,但是在这种情况下,我要做的是在插入子文档的ID之前先生成它。

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);
});
Run Code Online (Sandbox Code Playgroud)

这样,即使在保存和回调之间还有其他数据库操作,也不会影响已经创建的ID。