通过2个字段更新数组过滤

时间:2018-09-28 07:12:08

标签: mongodb mongoose

我不知道是否可能。

我正在尝试执行一个自动过程来更新某些文档中嵌套数组的所有元素。数组没有固定长度。

以下是集合的简化示例:

{
    "_id" : ObjectId("5ba2e413a4dd01725a658c63"),
    "MyOwnID" : "123456789",
    "MyArray" : [ 
        {
            Field1: 'FooName1',
            Field2: 'FooSpec1',
            FieldToUpdate: '...'
        },
        {
            Field1: 'FooName1',
            Field2: 'FooSpec2',
            FieldToUpdate: '...'
        },
        {
         ... More elements ...
        }
    ]
},
{
    "_id" : ObjectId("5ba2e413a4dd01725a658c63"),
    "MyOwnID" : "987654321",
    "MyArray" : [ 
        {
            Field1: 'FooName1',
            Field2: 'FooSpec1',
            FieldToUpdate: '...'
        },
        {
            Field1: 'FooName2',
            Field2: 'FooSpec2',
            FieldToUpdate: '...'
        },

    ]
}

我尝试过,它对第一个元素有效:

查询第二个元素:

db.getCollection('works').findOneAndUpdate(
    { MyOwnID: '123456789', '$and':[ { 'MyArray.Field1': 'FooName1' },{ 'MyArray.Field2': 'FooSpec1' } ] } , 
    { '$set': { 'MyArray.$.FieldToUpdate': 1234} } 
) 

但是当我尝试更新第二个元素时,只有第一个被更新。

查询第二个元素:

db.getCollection('works').findOneAndUpdate(
        { MyOwnID: '123456789', '$and':[ { 'MyArray.Field1': 'FooName1' },{ 'MyArray.Field2': 'FooSpec2' } ] } , 
        { '$set': { 'MyArray.$.FieldToUpdate': 4321} } 
    ) 

我尝试使用arrayFilters选项和$ elemMatch,都给我一个错误。

有什么选择吗?

2 个答案:

答案 0 :(得分:1)

您可以使用$elemMatch

尝试以下查询
db.getCollection("works").findOneAndUpdate(
  {
    "MyOwnID": "123456789",
    "MyArray": { "$elemMatch": { "Field1": "FooName1", "Field2": "FooSpec2" }}
  },
  { "$set": { "MyArray.$.FieldToUpdate": 4321 }} 
)

答案 1 :(得分:1)

您尝试过使用arrayFilters,但可能是错误的方式,因为它正在使用它。在mongoDB文档中不是很清楚,但是$ [myRef]充当arrayFilters的占位符。知道这一点,您可以这样做以实现您的目标:

db['01'].findOneAndUpdate(
  {MyOwnID: '123456789'},
  {$set:{"MyArray.$[object].FieldToUpdate":1234}},
  {arrayFilters:[{ $and:[{'object.Field1': 'FooName1' },{ 'object.Field2': 'FooSpec1' }]}]}
)

请注意,需要使用arrayFilters中的唯一文档(使用$ and运算符),因为这两个条件都引用了占位符。如果您设置2个条件,

  

({arrayFilters:[{'object.Field1':'FooName1'},{'object.Field2':   'FooSpec1'}]})

MongoDB将抱怨具有相同基本占位符的两个条件。

虽然@Anthony Winzlet给出的答案是正确的并且可以正常工作,但它只会更新$ elemMatch中定义的第一个数组元素匹配条件,这就是为什么我避免像这样使用它(除非在包含MyArray时具有唯一索引) .Field1和MyArray.Field2,则不能确保匹配的元素在数组中是唯一的)