【问题标题】:How can I update a property within an array of objects based on it's existing value in Mongo?如何根据 Mongo 中的现有值更新对象数组中的属性?
【发布时间】:2021-05-29 09:23:36
【问题描述】:

我有一些具有以下结构的文档...

{
    user: "Joe",
    lists: [
        { listId: "1234", listName: "dogs" },
        { listId: "5678", listName: "cats" }
    ]
}

我正在尝试为每个 listId 字段添加一个字符串,但我被卡住了。在我尝试过的其他事情中......

db.users.updateMany(
    {"lists.listId": /^[0-9a-f]{20,}$/},
    [{$set:
        {"lists.listId.$[]": {"$concat": ["0000", "$lists.listId"]}}
    }]
)

但我收到错误消息:“FieldPath 字段名称可能不以'$'开头”

此写入的变化结果进入适当的字段,但不是我想要的结果。

我已经对文档猛烈抨击了几个小时,但是我能找到的所有使用位置运算符引用正在更新的字段的值的引用都直接使用字段名称,而不是作为像我一样的财产。我之前并没有真正搞乱管道,我发现这有点令人困惑!昨天有人好心地帮助了我closely related problem,使用$map,这对于一个普通的字符串数组非常有效,但我没有任何运气将它适应一个具有字符串属性的对象数组。抱歉,如果这是 Mongo 101,文档很好,但其中有很多,我不确定哪些位与此相关。

【问题讨论】:

  • 您是否尝试为集合中的所有文档更新 lists 数组中的所有项目?
  • 是的,就是这样。这是一次性操作/迁移。

标签: mongodb mongoose


【解决方案1】:

你可以这样做:

db.collection.users({},
[
  {
    "$set": {
      lists: {
        $map: {
          input: "$lists",
          in: {
            $mergeObjects: [
              {
                "listName": "$$this.listName",
                "listId": {
                  $concat: [
                    "0000",
                    "$$this.listId"
                  ]
                }
              }
            ]
          }
        }
      }
    }
  }
],
{
  "multi": true
})

下面是工作示例:https://mongoplayground.net/p/Q8kUTB6X5JY

【讨论】:

  • 谢谢一百万老兄!令人费解的是,今天晚上我在某个时间点得到了几个字符,但我从没想过要尝试 $$this.listId。非常感谢您的帮助!
  • 实际上我刚刚尝试过,虽然它正确地将零添加到 listIds,但它用那些更新的 listIds 替换了原始对象。我需要一些可以更改 listId 字段的东西(并且还保留 listNames 原样)。我的例子不清楚,我会更新它。对不起。
  • 哦,你是对的。让我再检查一遍。
  • 我更新了我的代码。你能再检查一遍吗?
  • 是的,Nenad 非常好用,非常感谢您的宝贵时间!
猜你喜欢
  • 1970-01-01
  • 2020-12-23
  • 2021-11-25
  • 2019-03-09
  • 2017-12-13
  • 1970-01-01
  • 2021-05-18
  • 2020-09-07
  • 1970-01-01
相关资源
最近更新 更多