如何在MongoDB中多次更新嵌套数组?

时间:2014-10-18 10:40:42

标签: mongodb mongodb-query multidimensional-array

我在MongoDB'playground'集合中有以下“架构”后面的文档:

{
  "_id": ObjectId("54423b40c92f9fffb486a6d4"),

  "ProjectFileId": 1,
  "SourceLanguageId": 2,

  "TargetSegments": [
    {
      "LanguageId": 1,
      "Segment": "Something",
      "Colors": [
        1,
        2,
        3
      ],
      "Heights": [
        1,
        2,
        3
      ],
      "Widths": [
        1,
        2,
        3
      ]
    },
    {
      "LanguageId": 1,
      "Segment": "Something",
      "Colors": [
        1,
        2,
        3
      ],
      "Heights": [
        1,
        2,
        3
      ],
      "Widths": [
        1,
        2,
        3
      ]
    }
  ]
}

以下更新查询:

db.playground.update({
  $and: [
    {
      "TargetSegments.Colors": {
        $exists: true
      }
    },
    {
       "ProjectFileId": 1
    },
    {
      "SourceLanguageId": 2
    },
    {
      "TargetSegments": {
        $elemMatch: {
          "LanguageId": 1
        }
      }
    }
  ]
},
{
  $set: {
    "TargetSegments.$.Segment": null,
    "TargetSegments.$.Colors": [],
    "TargetSegments.$.Widths": [],
    "TargetSegments.$.Heights": []
  }
},
false, true)

执行查询后,结果为:

{
  "_id": ObjectId("54423b40c92f9fffb486a6d4"),

  "ProjectFileId": 1,
  "SourceLanguageId": 2,

  "TargetSegments": [
    {
      "LanguageId": 1,
      "Segment": null,
      "Colors": [],
      "Heights": [],
      "Widths": []
    },
    {
      "LanguageId": 1,
      "Segment": "Something",
      "Colors": [
        1,
        2,
        3
      ],
      "Heights": [
        1,
        2,
        3
      ],
      "Widths": [
        1,
        2,
        3
      ]
    }
  ]
}

如您所见,只更新了“TargetSegments”数组的第一个元素。

如何在一个更新查询中更新TargetSegments数组的所有元素?

1 个答案:

答案 0 :(得分:1)

因为您正在使用$运算符:位置$运算符标识要更新的数组中的元素(非多数),而不显式指定数组中元素的位置。要从读取操作中投影或返回数组元素,请参阅$ projection运算符。

您可以使用以下代码执行此操作:

db.playground.find({
  $and: [
    {
      "TargetSegments.Colors": {
        $exists: true
      }
    },
    {
       "ProjectFileId": 1
    },
    {
      "SourceLanguageId": 2
    },
    {
      "TargetSegments": {
        $elemMatch: {
          "LanguageId": 1
        }
      }
    }
  ]
}).forEach(function(item)
{
    var targets = item.TargetSegments;

    for(var index = 0; index < targets.length; index++)
    {
        var target = targets[index];
        target.Segment = null,
        target.Colors= [],
        target.Widths= [],
        target.Heights= []
    }

    db.playground.save(item);
});