0

我想一次对多个子文档进行更新查询。我会将所有子文档状态设置为被动,只要它们满足我在查询时给出的条件。

db.deduplications.update(  
{ $and: [ 
    { "_id": "189546D623FC69E3B693FDB679DBC76C" }, 
    { "DeviceVersionPairs.DeviceId": ObjectId("5822d0606bfdcd6ec407d9b9") }, 
    { "DeviceVersionPairs.CloudFolderId": ObjectId("5823110e6bfdd46ec4357582") },
    { "DeviceVersionPairs.CloudFileId": ObjectId("582311168cd396223499942a") },
    { "DeviceVersionPairs.VersionId": ObjectId("582311168cd396223499942b") }
] },
{ $set: { "DeviceVersionPairs.$.Status": "passive" }});

上面的查询恰好找到了一个子文档,然后根据我的需要进行更新。但;

db.deduplications.update(  
{ $or: [ { $and: [ 
        { "_id": "189546D623FC69E3B693FDB679DBC76C" }, 
        { "DeviceVersionPairs.DeviceId": ObjectId("5822d0606bfdcd6ec407d9b9") }, 
        { "DeviceVersionPairs.CloudFolderId": ObjectId("5823110e6bfdd46ec4357582") },
        { "DeviceVersionPairs.CloudFileId": ObjectId("582311168cd396223499942a") },
        { "DeviceVersionPairs.VersionId": ObjectId("582311168cd396223499942b") }
    ] } ,   
    { $and: [ 
        { "_id": "189546D623FC69E3B693FDB679DBC76C" }, 
        { "DeviceVersionPairs.DeviceId": ObjectId("56dfe1356caaea14a819f1e4") }, 
        { "DeviceVersionPairs.CloudFolderId": ObjectId("583fb4bc6e7f341874f13bfc") }, 
        { "DeviceVersionPairs.CloudFileId": ObjectId("583fb539e015b8a53fb71872") }, 
        { "DeviceVersionPairs.VersionId": ObjectId("583fb4ca6e7f331874213584") }
    ] } ] },
{ $set: { "DeviceVersionPairs.$.Status": "passive" }});

当我用或填充查询段并添加其他项目时,它会给出错误:

WriteResult({
    "nMatched" : 0,
    "nUpserted" : 0,
    "nModified" : 0,
    "writeError" : {
        "code" : 16837,
        "errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: DeviceVersionPairs.$.Status"
    }
})

我在这里想念什么?

4

5 回答 5

3

你收到了这个错误

位置运算符未从查询中找到所需的匹配项

因为您的第二个查询与多个 sub-document匹配。目前,无法使用位置运算符来使用位置运算符更新数组中的所有项目。

所以要解决你的问题,你可以按照这个过程

  1. 使用 _id 查找文档并使用$elemMatch查找子文档 ,然后

  2. 更新每个子文档并再次保存文档

可以这样尝试:

db.deduplications.find(  
{ $or: [ {
         "_id": ObjectId("583fc558668bde730a460e11") , 
        "DeviceVersionPairs":{
            $elemMatch:{ "DeviceId": ObjectId("5822d0606bfdcd6ec407d9b9") , 
            "CloudFolderId": ObjectId("5823110e6bfdd46ec4357582") ,
            "DeviceVersionPairs.CloudFileId": ObjectId("582311168cd396223499942a") ,
            "DeviceVersionPairs.VersionId": ObjectId("582311168cd396223499942b") }}
    } ,   
    { 
        "_id": ObjectId("583fc558668bde730a460e11") , 
        "DeviceVersionPairs":{
            $elemMatch:{ "DeviceId": ObjectId("56dfe1356caaea14a819f1e4") , 
            "CloudFolderId": ObjectId("583fb4bc6e7f341874f13bfc") , 
            "CloudFileId": ObjectId("583fb539e015b8a53fb71872") , 
            "VersionId": ObjectId("583fb4ca6e7f331874213584") }}
    } ] 
}).forEach(function (doc) {
    doc.DeviceVersionPairs.forEach(function (device) {
      device.status = 'passive';
    });
    db.deduplications.save(doc);
 });
于 2016-12-01T07:11:07.717 回答
0

不太确定你想要什么,但如果我是对的,你想要的可能是 $elemMatch。

请参阅MongoDB 更新手册$elemMatch

当您想查询嵌入式文档时,您不能直接使用 $and 和 $or,这是 mongodb 的某种“错误”。

于 2016-12-01T06:58:35.303 回答
0

使用方法UpdateMany()更新文档。根据框架和语言,此方法会有所不同,例如Update({multi : true});UpdateAll({});`

例如 :

db.collection.updateMany(
   <filter>,
   <update>
);

用来$set写。

参考:https ://docs.mongodb.com/v3.2/reference/method/db.collection.updateMany/

try {
   db.restaurant.updateMany(
      { $or: []
      },
      { $set: { "DeviceVersionPairs.$.Status": "passive" } }
   );
} catch (e) {
   print(e);
} 
于 2016-12-01T07:34:18.667 回答
0

我已经运行以下查询。它工作得很好。

db.mm.update( { $or: [ {$and: [{"_id": ObjectId("581d18d41b6c5c752f11c87a")}] }, 
                       {$and: [{"_id": ObjectId("581a1a671b6c5c752f11c87b")}] } 
               ] 
          }, {$set : {"name": "abc3"}});

如果未找到第一个文档,则更新第二个文档。如果找到第一个,它只会更新第一个。

您可以在您的问题 -> 显示的错误消息中看到"nMatched" : 0。它没有找到任何文件。确认所有 ID 和参考 ID。

于 2016-12-01T08:56:48.610 回答
0

请查看数组过滤器是否有帮助

db.deduplications.updateMany(
{ $or: [ { $and: [ 
        { "_id": "189546D623FC69E3B693FDB679DBC76C" }, 
        { "DeviceVersionPairs.DeviceId": ObjectId("5822d0606bfdcd6ec407d9b9") }, 
        { "DeviceVersionPairs.CloudFolderId": ObjectId("5823110e6bfdd46ec4357582") },
        { "DeviceVersionPairs.CloudFileId": ObjectId("582311168cd396223499942a") },
        { "DeviceVersionPairs.VersionId": ObjectId("582311168cd396223499942b") }
    ] } ,   
    { $and: [ 
        { "_id": "189546D623FC69E3B693FDB679DBC76C" }, 
        { "DeviceVersionPairs.DeviceId": ObjectId("56dfe1356caaea14a819f1e4") }, 
        { "DeviceVersionPairs.CloudFolderId": ObjectId("583fb4bc6e7f341874f13bfc") }, 
        { "DeviceVersionPairs.CloudFileId": ObjectId("583fb539e015b8a53fb71872") }, 
        { "DeviceVersionPairs.VersionId": ObjectId("583fb4ca6e7f331874213584") }
    ] } ] },


     { $set: {
         "DeviceVersionPairs.index.Status": "passive" ,
       }
     },
    { 
    arrayFilters: [ 
            { $or: [ { $and: [ 
        { "index.DeviceId": ObjectId("5822d0606bfdcd6ec407d9b9") }, 
        { "index.CloudFolderId": ObjectId("5823110e6bfdd46ec4357582") },
        { "index.CloudFileId": ObjectId("582311168cd396223499942a") },
        { "index.VersionId": ObjectId("582311168cd396223499942b") }
    ] } ,   
    { $and: [ 
        { "index.DeviceId": ObjectId("56dfe1356caaea14a819f1e4") }, 
        { "index.CloudFolderId": ObjectId("583fb4bc6e7f341874f13bfc") }, 
        { "index.CloudFileId": ObjectId("583fb539e015b8a53fb71872") }, 
        { "index.VersionId": ObjectId("583fb4ca6e7f331874213584") }
    ] } ] }
          ]
    ,"multi":true, new:true
    },

    function (err, out) {
         //
    });
于 2020-08-31T07:04:12.997 回答