Reputation: 133
My question is similar to Remove Object from Nested Array by Multiple Criteria. The major difference is that I want to apply the arrayFilter
on the top-level array first and then apply another arrayFilter
on the nested array of the matched top-level array element.
First of all, here is the document sample I copied over from the post with some adjustments to suit my case...
{
"OtherField1" : ISODate("2016-05-06T05:09:14.589Z"),
"OtherField2" : "something",
"Distributions" : [
{
"DeliveryType" : 1,
"DeliverySubType" : 2,
"DistributionData" : [
{
"Key" : "Topic",
"Value" : "Topics",
"Children" : null
},
{
"Key" : "Message",
"Value" : "test",
"Children" : null
}
]
},
{
"DeliveryType" : 1,
"DeliverySubType" : 3,
"DistributionData" : [
{
"Key" : "Topic",
"Value" : "Topics",
"Children" : ""
},
{
"Key" : "Message",
"Value" : "test",
"Children" : null
}
]
}
]
}
What I want to achieve is to, first of all, locate the 2nd element of the top-level Distributions
array by matching "DeliveryType" : 1
and "DeliverySubType" : 3
, and then locate the 1st element of its nested DistributionData
array by matching "Key": "Topic"
and "Value" : "Topics"
, and finally update the Children
field of matched nested array element.
For the top-level match, I tried the following forms ...
{
"arrayFilters": [
{ "filter1" : {
"elemMatch" : {
"DeliveryType" : 1,
"DeliverySubType" : 3,
}
}
}
}
and referenced the filter as Distributions.$[filter1]...
, but it didn't work.
Or,
{
"arrayFilters": [
{ "filter1.Distributions" : {
"elemMatch" : {
"DeliveryType" : 1,
"DeliverySubType" : 3,
}
}
}
}
and referenced the filter as $[filter1].Distributions....
, but once again it failed with a parsing error.
All the examples I can found are about using the arrayFilters
on the nested arrays and myself had some success in that regard, but no matter how hard I tried to apply the same tricks to the filters on the top-level array, they just failed with all sorts of errors. Could anyone help please? Thanks.
Upvotes: 3
Views: 1612
Reputation: 10918
The solution is somewhat hidden but it's actually documented:
db.collection.update({}, {
$set: { "Distributions.$[distFilter].DistributionData.$[distDataFilter].Children": "new value" }
}, {
"arrayFilters": [
{
"distFilter.DeliveryType" : 1,
"distFilter.DeliverySubType" : 3
}, {
"distDataFilter.Key" : "Topic",
"distDataFilter.Value" : "Topics"
}
]
})
Upvotes: 5