Home > Net >  Remove multiple objects from nested array 4
Remove multiple objects from nested array 4

Time:11-07

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?

Playground example

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

  • Related