Mongodb 重命名对象数组中的键

发布于 2025-01-16 21:51:24 字数 836 浏览 1 评论 0原文

我正在尝试更新数组对象内的键的名称,并且由于无法使查询工作而感到恼火。我已经尝试过这个 如何重命名对象数组中的嵌套键在 MongoDB 中? 但我仍然遇到与之前相同的错误

这是文档:

[
  {
  "accountCreation": [
      {
        "startDateTime": "",
        "endDateTime": "",
        "isDone": "Yes"
      }
    ]
  }
]

这是我的查询:

db.collection.update({}, $rename:{
  "accountCreation.$.isDone":"done",
})

我想做的就是将 isDone 键重命名为完成。请注意,这只是具有此键的众多对象之一。我正在尝试将 accountCreation 内出现的所有 isDone 键更新为 done

这是我收到的错误:

fail to run update: write exception: write errors: [cannot use the part (accountCreation of accountCreation.isDone) to traverse the element

I am trying to update the name of a key inside an object of an array and annoyed due to the inability to make the queries work. I have tried this How rename nested key in array of object in MongoDB? but I still get the same error I was getting earlier

Here is the document:

[
  {
  "accountCreation": [
      {
        "startDateTime": "",
        "endDateTime": "",
        "isDone": "Yes"
      }
    ]
  }
]

Here is my query:

db.collection.update({}, $rename:{
  "accountCreation.$.isDone":"done",
})

All I am trying to do is rename the isDone key to done. Note that this is just one of the many objects that have this key. I am trying to update all the occurences of the isDone key to done inside the accountCreation

Here is the error I am receiving:

fail to run update: write exception: write errors: [cannot use the part (accountCreation of accountCreation.isDone) to traverse the element

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半世蒼涼 2025-01-23 21:51:24

实际上,您提供的链接的答案已经指出 $rename 不适用于数组。

尽管如此,您可能可以通过使用带有更新的聚合来实现您的预​​期行为。如果您有其他字段,您将需要使用 $objectToArray$arrayToObject 来处理对象。

db.collection.update({},
[
  {
    "$project": {
      accountCreation: {
        "$map": {
          "input": "$accountCreation",
          "as": "ac",
          "in": {
            "$objectToArray": "$ac"
          }
        }
      }
    }
  },
  {
    "$project": {
      accountCreation: {
        "$map": {
          "input": "$accountCreation",
          "as": "ac",
          "in": {
            "$map": {
              "input": "$ac",
              "as": "kv",
              "in": {
                "$cond": {
                  "if": {
                    $eq: [
                      "$kv.k",
                      "isDone"
                    ]
                  },
                  "then": {
                    "k": "done",
                    "v": "$kv.v"
                  },
                  "else": "$kv"
                }
              }
            }
          }
        }
      }
    }
  },
  {
    "$project": {
      accountCreation: {
        "$map": {
          "input": "$accountCreation",
          "as": "ac",
          "in": {
            "$arrayToObject": "$ac"
          }
        }
      }
    }
  }
])

这是 Mongo Playground 供您参考。

Actually, the answers to the link you provided already stated that $rename does not work with array.

Nevertheless, you could probably achieve your expected behaviour by using an aggregate with update. You will need to use $objectToArray and $arrayToObject to wrangle the objects if you have other fields.

db.collection.update({},
[
  {
    "$project": {
      accountCreation: {
        "$map": {
          "input": "$accountCreation",
          "as": "ac",
          "in": {
            "$objectToArray": "$ac"
          }
        }
      }
    }
  },
  {
    "$project": {
      accountCreation: {
        "$map": {
          "input": "$accountCreation",
          "as": "ac",
          "in": {
            "$map": {
              "input": "$ac",
              "as": "kv",
              "in": {
                "$cond": {
                  "if": {
                    $eq: [
                      "$kv.k",
                      "isDone"
                    ]
                  },
                  "then": {
                    "k": "done",
                    "v": "$kv.v"
                  },
                  "else": "$kv"
                }
              }
            }
          }
        }
      }
    }
  },
  {
    "$project": {
      accountCreation: {
        "$map": {
          "input": "$accountCreation",
          "as": "ac",
          "in": {
            "$arrayToObject": "$ac"
          }
        }
      }
    }
  }
])

Here is the Mongo playground for your reference.

原谅过去的我 2025-01-23 21:51:24

这可以分两步完成(mongoDB 4.2+):

第 1 步:添加新字段“done”

db.collection.update({
   "accountCreation": {
          $exists: true
      }
   },
   [
   {
     "$addFields": {
       accountCreation: {
         "$map": {
           "input": "$accountCreation",
           "as": "ac",
           "in": {
          $mergeObjects: [
          "$ac",
          {
            "done": "$ac.isDone"
          }
         ]
        }
      }
     }
   }
 }
],
{
  multi: true
})

解释:

在 isDone 所在的所有数组元素中添加字段“Done”=“$isDone”成立。

playground_step_1

第 2 步:删除旧字段“isDone”:

  db.collection.update({
   "accountCreation.isDone": {
   "$exists": true
  }
 },
 {
  "$unset": {
    "accountCreation.$[x].isDone": true
 }
},
{
  arrayFilters: [
 {
  "x.isDone": {
    $exists: true
  }
}
],
   multi: true
})

解释:

定义arrayFilter x 并从找到的所有数组元素中删除旧字段“isDone”

playground_step_2

(当然需要先执行步骤1!!!)

This can be done in two steps(mongoDB 4.2+):

Step 1: Add the new field "done"

db.collection.update({
   "accountCreation": {
          $exists: true
      }
   },
   [
   {
     "$addFields": {
       accountCreation: {
         "$map": {
           "input": "$accountCreation",
           "as": "ac",
           "in": {
          $mergeObjects: [
          "$ac",
          {
            "done": "$ac.isDone"
          }
         ]
        }
      }
     }
   }
 }
],
{
  multi: true
})

Explained:

Add the field "Done"="$isDone" in all array elements where isDone is found.

playground_step_1

Step 2: Remove the old field "isDone":

  db.collection.update({
   "accountCreation.isDone": {
   "$exists": true
  }
 },
 {
  "$unset": {
    "accountCreation.$[x].isDone": true
 }
},
{
  arrayFilters: [
 {
  "x.isDone": {
    $exists: true
  }
}
],
   multi: true
})

Explained:

Define arrayFilter x and remove the old field "isDone" from all array elements where it is found

playground_step_2

( Afcourse Step 1 need to be executed first!!! )

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文