使用位置运算符

时间:2016-10-18 12:41:11

标签: mongodb

让我们说我有一个集合' myCollection'以这种方式构建的文件:

{
    _id: ...,
    Items: [
        {
        Field1: ..., 
        Field2:..., 
        Value: 0
        }
    ]
}

我想更新字段"价值"当我在_id,Item.Field1和Item.Field2上得到一个匹配。

这是我的问题:

db['myCollection'].update({
        "_id" : BinData(3, "xxx"), 
        "Items.Field1" : ISODate("2016-05-01T00:00:00.000+0000"), 
        "Items.Field2" : BinData(3, "yyy")
    }, 
     {
        $set : {
            "Items.$.Value" : NumberInt(11)
        }
    }
)

有时它可以工作,有时字段值不会使用以下响应更新:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

该项目已被发现但尚未修改?...

据我了解" $"在这种情况下,我认为数组的索引是正确的,但也许问题是关于" _id"标准是什么?

我怀疑$ set表达式是错误的:也许我错过了一些东西,以确保$ set的目标是{" _id" :BinData(3," xxx")}?

非常感谢

修改 似乎writeResult.Modified为false,因为已经使用值设置了需要修改的字段。 实际上对于任何Field1和Field2标准,更改的项始终是相同的:在我的情况下为Items.0.Value。 可能是因为第一个标准" _id"哪个不是项目数组的一部分?

修改 在我看来,Field2标准覆盖了Field1:如果我只保留其中一个,则会正确考虑它。 但如果我同时保留它们,就好像第一个被滑雪了......

1 个答案:

答案 0 :(得分:0)

确定。经过进一步调查后,我发现了问题:我需要使用$ elemMatch运算符,因为我的数组有多个条件:

查询部分类似于:

{
    "_id" : BinData(3, "xxx"), 
    "Items" : { 
         $elemMatch { 
             "Field1": ISODate("2016-05-01T00:00:00.000+0000"), 
             "Field2" : BinData(3, "yyy")
     }}

}

感谢那些花时间阅读的人。希望这可以提供帮助。

如果有人解释我们在这种情况下必须使用$ elemMatch的原因,我非常感兴趣!