please, help in my attempt to clean my documents from corrupted sub-objects , few solutions proposed in previous questions work for most of the cases , but there is specific cases where there is more objects at same nested level that shall not be cleaned:
Example document:
{
"_id": ObjectId("5c05984246a0201286d4b57a"),
f: "x",
"_a": [
{
"_onlineStore": {}
},
{
"_p": {
"s": {
"a": {
"t": [
{
id: 1,
"dateP": "20200-09-20",
did: "x",
dst: "y",
den: "z"
},
{
id: 2,
"dateP": "20200-09-20"
}
]
},
"c": {
"t": [
{
id: 3,
"dateP": "20300-09-22"
},
{
id: 4,
"dateP": "20300-09-23",
did: "x",
dst: "y",
den: "z"
},
{
id: 5,
"dateP": "20300-09-23"
}
]
}
},
h: "This is cleaned but it shauld not"
}
}
]
}
All objects where did,dst,den are missing from _a._p.s.[a|c|d].t need to be removed , expected result:
[
{
"_a": [
{
"_onlineStore": {}
},
{
"_p": {
"s": {
"a": {
"t": [
{
"dateP": "20200-09-20",
"den": "z",
"did": "x",
"dst": "y",
"id": 1
}
]
},
"c": {
"t": [
{
"dateP": "20300-09-23",
"den": "z",
"did": "x",
"dst": "y",
"id": 4
}
]
}
},
h: "This is cleaned but it shauld not"
}
}
],
"_id": ObjectId("5c05984246a0201286d4b57a"),
"f": "x"
}
]
Very good solutions provided by @nimrod serok & @rickhg12hs here: , but unfortunatelly not working for all cases , for example for cases where there is more key/values at the level "_a._p" beside "s" the other key/values beside "s" are cleaned like _a._p.h:"..." in the example , please, advice if there is any easy option to be solved with mongo update query?
CodePudding user response:
One option is to add $mergeObjects
to the party:
db.collection.update({},
[
{
"$set": {
"_a": {
"$map": {
"input": "$_a",
"as": "elem",
"in": {
"$cond": [
{
$or: [
{
"$eq": [
{
"$type": "$$elem._p"
},
"missing"
]
},
{
"$eq": [
{
"$type": "$$elem._p.s"
},
"missing"
]
}
]
},
"$$elem",
{
$mergeObjects: [
"$$elem._p",
{
"s": {
"$arrayToObject": {
"$map": {
"input": {
"$objectToArray": "$$elem._p.s"
},
"as": "anyKey",
"in": {
"k": "$$anyKey.k",
"v": {
"t": {
"$filter": {
"input": "$$anyKey.v.t",
"as": "t",
"cond": {
"$setIsSubset": [
[
"did",
"dst",
"den"
],
{
"$map": {
"input": {
"$objectToArray": "$$t"
},
"in": "$$this.k"
}
}
]
}
}
}
}
}
}
}
}
}
]
}
]
}
}
}
}
}
],
{
"multi": true
})
See how it works on the playground example