MongoDB 使用或查询更新多个子文档
MongoDB update multiple subdocuments with or query
我想同时对多个子文档进行更新查询。我会将所有子文档状态设置为被动,它们满足我在查询时给出的条件。
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" }});
当我用 or 填充查询段并添加其他项目时出现错误:
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"
}
})
我在这里错过了什么?
不太确定你想要什么,但如果我是对的,你想要的可能是 $elemMatch。
参考MongoDB Update Manual , and $elemMatch
当你想查询嵌入文档时,你不能直接使用$and和$or,这是mongodb的某种'bug'。
你遇到了这个错误
The positional operator did not find the match needed from the query
因为您的第二个查询与 多个子文档 匹配。目前无法使用 位置运算符 来更新使用位置运算符的数组中的所有项目。
所以要解决你的问题,你可以按照这个过程
使用 _id 查找文档,使用 $elemMatch 查找子文档
然后
更新每个子文档并再次保存文档
可以这样试试:
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);
});
使用方法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);
}
我有 运行 下面的查询。而且效果非常好。
db.mm.update( { $or: [ {$and: [{"_id": ObjectId("581d18d41b6c5c752f11c87a")}] },
{$and: [{"_id": ObjectId("581a1a671b6c5c752f11c87b")}] }
]
}, {$set : {"name": "abc3"}});
如果找不到第一个文档,则更新第二个。如果找到第一个,它只会更新第一个。
您可以在您的问题 -> 错误消息中看到它显示 "nMatched" : 0
。它没有找到任何文件。确认所有 ID 和参考 ID。
请查看数组过滤器是否有帮助
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) {
//
});
我想同时对多个子文档进行更新查询。我会将所有子文档状态设置为被动,它们满足我在查询时给出的条件。
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" }});
当我用 or 填充查询段并添加其他项目时出现错误:
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"
}
})
我在这里错过了什么?
不太确定你想要什么,但如果我是对的,你想要的可能是 $elemMatch。
参考MongoDB Update Manual , and $elemMatch
当你想查询嵌入文档时,你不能直接使用$and和$or,这是mongodb的某种'bug'。
你遇到了这个错误
The positional operator did not find the match needed from the query
因为您的第二个查询与 多个子文档 匹配。目前无法使用 位置运算符 来更新使用位置运算符的数组中的所有项目。
所以要解决你的问题,你可以按照这个过程
使用 _id 查找文档,使用 $elemMatch 查找子文档 然后
更新每个子文档并再次保存文档
可以这样试试:
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);
});
使用方法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);
}
我有 运行 下面的查询。而且效果非常好。
db.mm.update( { $or: [ {$and: [{"_id": ObjectId("581d18d41b6c5c752f11c87a")}] },
{$and: [{"_id": ObjectId("581a1a671b6c5c752f11c87b")}] }
]
}, {$set : {"name": "abc3"}});
如果找不到第一个文档,则更新第二个。如果找到第一个,它只会更新第一个。
您可以在您的问题 -> 错误消息中看到它显示 "nMatched" : 0
。它没有找到任何文件。确认所有 ID 和参考 ID。
请查看数组过滤器是否有帮助
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) {
//
});