【问题标题】:Updating embedded document property in Mongodb更新 Mongodb 中的嵌入文档属性
【发布时间】:2011-07-20 07:19:28
【问题描述】:

我有一个如下所示的文档:

{
    "_id": 3,
    "Slug": "slug",
    "Title": "title",
    "Authors": [
        {
            "Slug": "slug",
            "Name": "name"
        }
    ]
}

我想根据 Authors.Slug 更新所有 Authors.Name。 我试过了,但没有用:

.update({"Authors.Slug":"slug"}, {$set: {"Authors.Name":"zzz"}});

我在这里做错了什么?

【问题讨论】:

  • "{ "_id" : 3, "Slug" : "slug", "Title" : "title", "Authors" : [ "Slug" : "slug", "Name" : " name"] }" 不是有效文档。如果您提供示例数据,请提供 working 示例数据。
  • 我错过了一些花括号。现在是有效文件。
  • 这是我的问题。我想知道为什么更新不起作用
  • 看一下“位置运算符”和$elemMatch
  • 位置运算符正是我所需要的。这对更新有效: .update({"Authors.Slug":"slug"}, {$set: {"Authors.$.Name":"zzz"}});

标签: mongodb


【解决方案1】:
.update(Authors:{$elemMatch:{Slug:"slug"}}, {$set: {'Authors.$.Name':"zzz"}});

【讨论】:

  • 您不需要使用 elemMatch 来执行此操作。第二部分中的“$”起到了作用。见这里:mongodb.org/display/DOCS/Updating/…
  • 不一定正确。查询部分必须唯一标识位置运算符的数组元素,并且 {Authors.Slug:"slug"} 在语义上不等同于 $elemMatch 版本。 $elemMatch 版本会进行部分匹配,即使您在同一元素中有多个字段要匹配,这也是执行这些操作的更好方法。
  • 我知道这是一个旧答案,但我很难真的理解使用 $elemMatch 进行的查询与其“正常”等效项(如上)之间的区别。 “即使您在同一个元素中有多个字段要匹配,$elemMatch 版本也会进行部分匹配”是什么意思?
  • @Merc :假设您的数组中的元素具有字段“a”和字段“b”:arr:[{a:1, b:1}, {a:2, b:10} , ...]。在这种情况下, arr:{$elemMatch:{a:1}} 将匹配第一个元素(该元素有一个值为 1 的字段“a”)位 arr:{a:1} 不会匹配(元素是 {a: 1, b:1} 而不是 {a:1}。换句话说,如果没有 $elemMatch,数组中的整个元素都应该匹配,而不是一组特定的字段。
  • @Merc 不客气。此处的文档中有更详细的说明:docs.mongodb.org/manual/reference/operator/elemMatch
【解决方案2】:

您可以将更新与数组过滤器一起使用:
https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/#positional-update-arrayfilters

大概是这样的:

yourcollection.update(
{},
{
    "$set": {
        "Authors.$[element].Name": "zzz"
    }
},
{
    "multi": true,
    "arrayFilters": [
         { "element.Slug": "slug" }
    ]
}
)

Ps.:它在 Robo3T 中不起作用,如下所述:Mongodb 3.6.0-rc3 array filters not working? 但是,您可以尝试使用版本 >= 3.6 的 mongo shell。

【讨论】:

    【解决方案3】:

    是的,Rock 的解决方案很有效,P.S Notes 在尝试 Robo31 时非常有用。 如果我们要更新所有 db.collection_name.update({}, {$set: {"Authors.$[].Name": "zzz"}})

    如果我们想用数组中的匹配对象进行更新 db.collection_name.update({}, {$set: {"Authors.$[i].Name": "zzz"}}, {arrayFilters: [{"i.Slug": "slug"}]})

    参考:https://jira.mongodb.org/browse/SERVER-1243

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-27
      • 2011-12-04
      • 1970-01-01
      • 2018-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多