保存后访问子文档 ID - mongoose

Posted

技术标签:

【中文标题】保存后访问子文档 ID - mongoose【英文标题】:Accessing a sub-document ID after save - mongoose 【发布时间】:2016-08-10 00:20:16 【问题描述】:

当在我的应用程序上创建用户时,他们的详细信息会使用 mongoose 保存在 MongoDB 上。 user schema 包含子文档,如果使用 user.save 函数后的子文档,我正在尝试访问 _id

架构如下:


  name: String,
  email: String,
  address: String,
  phone:[
     landLine: Number,
      mobile: Number
   ]

我可以像这样轻松访问姓名、电子邮件和地址:

console.log(user.name + user.email + user.address)

我试过user.phone._id,但它返回undefined。我想是因为phone 是一个对象数组。

 user.save(function(err) 
                if (err)
                    throw err;
                else 
                    console.log("user ID " + user._id); // SUCCESS!!
                    console.log("user sub-document ID " + user.phone._id); // UNDEFINED!!
                    return (null, user);
                
            );

如何在创建用户并保存到 mongoDB 后立即访问 save 函数内的子文档的_id?

【问题讨论】:

在你的架构中 phone 不是子文档,所以它没有 _id @AlexanderMac 我认为问题没有正确显示架构。它可能真的是phone: [ landline: Number, mobile: Number ],但如果能得到确认会很好。当然,“第一个”元素是user.phone[0]._id,但在上下文中也不清楚这是一个数组元素的“初始”保存还是添加另一个元素 @NeilLunn 是的,对于您正确的架构感到抱歉。我会更新我的问题 看起来您仍然没有正确表示架构。 这几乎就是我所了解的,因此在您的问题中寻找一些上下文。实际上,您是如何向数组中添加其他项目的?更重要的是,在您实际申请添加到数组之前,数据实际上是如何进入的?这为不同的方法提供了一些背景信息。 【参考方案1】:

有几种方法可以获取此信息,但我个人更喜欢使用$push 的“原子”修改方法。

这里的实际实现是由 mongoose 自动包含一个“单调”的 ObjectId 值来帮助实现的,因此值总是在增加。所以这意味着我的处理方法甚至可以使用应用于$push$sort 修饰符。

例如:

// Array of objects to add
var newNumbers = [
   "landline": 55555555, "mobile": 999999999 ,
   "landline": 44455555, "mobile": 888888888 
];

User.findOneAndUpdate(
   "email": email ,
   "$push":  "phone":  "$each": newNumbers   ,
   "new": true ,
  function(err,user) 
    // The trick is to sort() on `_id` and just get the
    // last added equal to the length of the input
    var lastIds = user.phone.concat().sort(function(a,b) 
      return a._id > b._id
    ).slice(-newnumbers.length);
  
)  

即使你使用了$sort 修饰符:

User.findOneAndUpdate(
   "email": email ,
   "$push":  "phone":  "$each": newNumbers, "$sort":  "landline": 1     ,
   "new": true ,
  function(err,user) 
    var lastIds = user.phone.concat().sort(function(a,b) 
      return a._id > b._id
    ).slice(-newnumbers.length);
  
)  

_id 值上“排序”临时副本的小技巧意味着“最新”项目始终位于末尾。而且您只需要在更新中添加尽可能多的数量即可。

这里有争议的一点是,实际上是 mongoose 首先插入了 _id 值。所以实际上这些是在对每个数组项向服务器发出的请求中提交的。

您“可以”花哨并使用“钩子”来记录那些在更新语句中实际添加到新数组成员中的ObjectId 值。但这实际上只是从数组项中返回最后一个 n "greatest" _id 值的简单过程,因此不需要更复杂的方法。

【讨论】:

以上是关于保存后访问子文档 ID - mongoose的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose - 获取新保存的内部记录的_id

访问 mongoDB 中的子文档

子查询返回每个父 ID 的最新条目

如何将数据保存到 mongodb 中的子文档中?我正在将农场子文档转换为 null

ifram

Flash Professional CC JSFL侦听器,用于保存文档和发布后处理