I want to make an update query for multiple subdocuments at once. I will be setting all the subdocuments statuses to passive where they satisfy the condition I give on query. <
You got this error
The positional operator did not find the match needed from the query
because of your second query matched with multiple sub-document. Currently it is not possible to use the positional operator to update all items in an array using positional operator.
so to solve your problem you can follow this process
Find document using _id and to find sub document using $elemMatch and then
update each sub document and save document again
can try like this:
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);
});
Use method UpdateMany()
to update documents. According to framework and langauage this method will be different like Update({multi : true});
or UpdateAll({});`
For example :
db.collection.updateMany(
<filter>,
<update>
);
Use $set
to write.
Ref: https://docs.mongodb.com/v3.2/reference/method/db.collection.updateMany/
try {
db.restaurant.updateMany(
{ $or: []
},
{ $set: { "DeviceVersionPairs.$.Status": "passive" } }
);
} catch (e) {
print(e);
}
Not so sure about what do you want, but if I were right, what you want may be $elemMatch.
Refer to MongoDB Update Manual , and $elemMatch
When you wanna query into embedded documents, you can't use $and and $or directly, this is some kind of 'bug' of mongodb.
I have run below query. And it is working fantastic.
db.mm.update( { $or: [ {$and: [{"_id": ObjectId("581d18d41b6c5c752f11c87a")}] },
{$and: [{"_id": ObjectId("581a1a671b6c5c752f11c87b")}] }
]
}, {$set : {"name": "abc3"}});
If first document not found , second one is updated. And if 1st one is found it is updating only 1st one.
You can see that in your question -> Error message it is showing "nMatched" : 0
. It is not finding any documents. Confirm all ID's and reference ID's.
please see whether array filters will help
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) {
//
});