【问题标题】:Accessing a sub-document ID after save - mongoose保存后访问子文档 ID - 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 是的,对于您正确的架构感到抱歉。我会更新我的问题
  • 看起来您仍然没有正确表示架构。
  • 这几乎就是我所了解的,因此在您的问题中寻找一些上下文。实际上,您是如何向数组中添加其他项目的?更重要的是,在您实际申请添加到数组之前,数据实际上是如何进入的?这为不同的方法提供了一些背景信息。

标签: javascript node.js mongodb mongoose mongodb-query


【解决方案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 值的简单过程,因此不需要更复杂的方法。

【讨论】:

    猜你喜欢
    • 2014-04-07
    • 1970-01-01
    • 2021-05-15
    • 2015-07-03
    • 2017-10-06
    • 1970-01-01
    • 2016-07-30
    • 2019-07-14
    • 2020-05-15
    相关资源
    最近更新 更多