【问题标题】:Copy a nested String value to a new nested Object in mongodb [duplicate]将嵌套的字符串值复制到 mongodb 中的新嵌套对象 [重复]
【发布时间】:2019-10-13 17:38:09
【问题描述】:

我最初创建了一个字符串refillNote,我最近决定将其转换为对象数组refillNotes(见下文)。所以我需要将每个用户的refillNote 字符串(来自refills 对象数组)的字符串值复制到新对象中。

由于这两个项目嵌套在不同的层中,我无法使用$set 方法获取字符串数据并将其注入嵌套对象中。

这是用户对象:

{ 
   name:"Joe",
   refills: [ 
      { 
         refillNote: "original refill note",
         refillNotes: [
            { 
               note:"I need to copy the original refillNote here",
               username:"Tim"
            }
         ]
      }
   ]
}

我只是想从 refills 数组中获取现有的 refillNote 字符串值并创建一个新的 refillNotes 对象并将其注入到数组中,如上所示。

这是我用于将新对象添加到 refillNotes 数组的当前代码,但问题是,我无法获取 refillNote 值并在此处设置:

User.updateMany(
  {},
  {
    $set: {
      "refills.$.refillNotes": [
        { username: "Joe", note: "refills.$.refillNote" }
      ]
    }
  }
);

这当前将注释添加为文字字符串“refills.$.refillNote”,因此我不知道在此序列中的何处可以提取原始 refillNote 值并能够在此再次使用它$set 方法。任何意见将不胜感激。

编辑

最终使用了一个老旧的 forEach 解决方案(如下),我一直在避免这种做法,但如果有人遇到过这篇使用基于聚合器的 mongodb 解决方案(或缺少该解决方案)的帖子,那就太棒了。

  User.find({})
    .then(function(results) {
      return results.map(function(user) {
        user.refills.forEach(function(refill) {
          if (refill.refillNote) {
            refill.refillNotes = [
              { username: "Tim", note: refill.refillNote }
            ];
          } else {
            refill.refillNotes = [];
          }
        });
        return user.save();
      });
    })

【问题讨论】:

  • @matthPen 谢谢,但在我的情况下,这是一个没有嵌套级别的简单操作。您在他们的答案中看到的解决方案在这里不起作用。我包含的最后一部分说明了原因(在我的情况下,$ 的值被视为文字)。
  • 你真的需要 refillNotes 作为一个对象数组,在你 refills 数组里面吗?你用的是哪个版本?
  • @NeilLunn 您标记为“重复”的问题都没有回答我提出的问题,并且都提供了我完全了解的回答(如上所述)。我的问题特定于将原始嵌套数据传送到另一个深度嵌套的数组。我完全同意,它们绝对不是一个好主意,但我从另一个开发人员那里接手了这个应用程序,正在慢慢地将事情恢复正常,而无需重新编写(目前)。

标签: mongodb mongoose


【解决方案1】:

您需要使用$map 来应用到每个数组元素。 这就是你需要的:

db.collection.aggregate([
  {
    "$addFields": {
      "refills": {
        "$map": {
          input: "$refills",
          as: "refill",
          in: {
            refillNote: "$$refill.refillNote",
            refillNotes: [
              {
                "refillNote": "$$refill.refillNote",
                name: "Tim"
              }
            ]
          }
        }
      }
    }
  }, 
  {$out:'collection'}
])

会写:

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "name": "Joe",
    "refills": [
      {
        "refillNote": "original refill note",
        "refillNotes": [
          {
            "name": "Tim",
            "refillNote": "original refill note"
          }
        ]
      }
    ]
  }
]

如果您的 refills.refillNotesd 不需要是一个数组(因为它已经位于“refills”数组中),只需删除上述聚合中的数组元素:

...
            refillNotes: {
                "refillNote": "$$refill.refillNote",
                name: "Tim"
              }
           } 
...

【讨论】:

  • 感谢您提供聚合管道解决方案。
猜你喜欢
  • 2018-11-07
  • 2018-11-23
  • 2014-06-01
  • 2018-07-19
  • 1970-01-01
  • 1970-01-01
  • 2017-10-25
  • 2021-12-06
相关资源
最近更新 更多