如何在数组中找到匹配值的最后一个元素并更新它?

时间:2017-09-21 10:24:54

标签: mongodb mongodb-query

我在MongoDB集合中有以下字段的文档:

var doc = {
container_id:12,
steps: [
    {
        name:'name1',
    },
    {
        name:'name2',
    }
]

}

我需要查找所有包含container_id == 12以及最后一步'步骤的文档。元素匹配&name;' name2'并使用新值更新它。

我尝试了以下内容:

let findQ = {'container_id': 12, "steps:{$slice:-1}.name": "name2"};
let updateQ = {"$set": {'steps.$.name': "new name3"}};

db.collection(myCollection).update(
  findQ,
  updateQ,
  {multi: true},
  function (err, doc) { ... }
);

2 个答案:

答案 0 :(得分:0)

您需要在语句的查询部分添加$where条件,以确保文档包含“last”位置中的数组匹配。但这只是一个“附加”约束,而“位置”应该从"steps.name": "name2"的标准查询选项获得:

所以给出样本文件:

/* 1 */
{
    "_id" : ObjectId("59c39cf859f55d64d6e30293"),
    "container_id" : 12.0,
    "steps" : [ 
        {
            "name" : "name1"
        }, 
        {
            "name" : "name2"
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("59c39d1b59f55d64d6e30294"),
    "container_id" : 12.0,
    "steps" : [ 
        {
            "name" : "name1"
        }, 
        {
            "name" : "name2"
        }, 
        {
            "name" : "name3"
        }
    ]
}

发出查询:

db.collection('junk').update(
  { 
    "container_id": 12,
    "steps.name": "name2",
    "$where": "this.steps.slice(-1)[0].name === 'name2'"
  },
  { "$set": { "steps.$.name": "new name4" } },
  { "multi": true }
)

结果:

/* 1 */
{
    "_id" : ObjectId("59c39cf859f55d64d6e30293"),
    "container_id" : 12.0,
    "steps" : [ 
        {
            "name" : "name1"
        }, 
        {
            "name" : "new name4"
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("59c39d1b59f55d64d6e30294"),
    "container_id" : 12.0,
    "steps" : [ 
        {
            "name" : "name1"
        }, 
        {
            "name" : "name2"
        }, 
        {
            "name" : "name3"
        }
    ]
}

因此第二个文档虽然包含匹配值为"name2"的数组元素,但却被$where子句排除,因为它不是数组中的最后一个元素。

只有第一个文档会更新,因为它符合两个条件。

  

注意:您仍然需要"steps.name": "name2"的查询部分中的.update()才能获得positional $ operator的排名。如果数组中实际上有多个匹配项用于相同的值,则此时无法执行此操作。 See How to Update Multiple Array Elements in MongoDB了解有关多场比赛的详细信息。

答案 1 :(得分:0)

根据上述问题的描述,请尝试在MongoDB shell中执行以下更新操作。

db.myCollection.update({
        "container_id": 12.0,
        steps: {
            $elemMatch: {
                "name": "name2"
            }
        }
    }, {
        $set: {
            'steps.$.name': 'name3'
        }
    }, {
        multi: true
    }


)