Home > Net >  Remove multiple elements from deep nested array with single update query
Remove multiple elements from deep nested array with single update query

Time:11-04

I have following type of ducuments:

[
 {
 "_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",
              
            }
          ]
        }
      }
    }
  }
]
}
]

I need to find update query that remove all documents that do not have "did" , "dst" and "den" fields , in the document nested array above this are the sub-objects with id:[2,3,5] , in the real collection I dont know the id's , is there option to remove all at once ?

My playground attempt , but unsuccessfull

The document after the update need to look like:

[
 {
 "_id": ObjectId("5c05984246a0201286d4b57a"),
f: "x",
"_a": [
  {
    "_onlineStore": {}
  },
  {
    "_p": {
      "s": {
        "a": {
          "t": [
            {
              id: 1,
              "dateP": "20200-09-20",
              did: "x",
              dst: "y",
              den: "z"
            }
          ]
        },
        "c": {
          "t": [
            {
              id: 4,
              "dateP": "20300-09-23",
              did: "x",
              dst: "y",
              den: "z"
            }
          ]
        }
      }
    }
  }
]
}
]

CodePudding user response:

Is this what you want?:

db.collection.update(
{},
[
  {
    $set: {
      "_a": {
        $map: {
          input: "$_a",
          as: "external",
          in: {
            $cond: [
              {
                $gt: [
                  "$$external._p",
                  0
                ]
              },
              {
                _p: {
                  s: {
                    a: {
                      t: {
                        $filter: {
                          input: "$$external._p.s.a.t",
                          as: "item",
                          cond: {
                            $and: [
                              {
                                $gt: [
                                  "$$item.did",
                                  0
                                ]
                              },
                              {
                                $gt: [
                                  "$$item.dst",
                                  0
                                ]
                              },
                              {
                                $gt: [
                                  "$$item.den",
                                  0
                                ]
                              }
                            ]
                          }
                        }
                      }
                    }
                  },
                  c: {
                    t: {
                      $filter: {
                        input: "$$external._p.s.c.t",
                        as: "item",
                        cond: {
                          $and: [
                            {
                              $gt: [
                                "$$item.did",
                                0
                              ]
                            },
                            {
                              $gt: [
                                "$$item.dst",
                                0
                              ]
                            },
                            {
                              $gt: [
                                "$$item.den",
                                0
                              ]
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              },
              "$$external"
            ]
          }
        }
      }
    }
  }
], 
{multi:true})

See how it works on the playground example

  • Related