Фильтровать элементы из массива на основе поля, используя условие $ nin - PullRequest
3 голосов
/ 03 февраля 2020

У меня есть документ mon go, как показано ниже;

{
    "_id": "123",
    "name": "ABC",
    "elements": {
        "_id": "123",
        "minorElements": [
            [
                {
                    "id": "xyz1",
                    "name": "xyz1"
                }, {
                    "id": "xyz2",
                    "name": "xyz2"
                }, {
                    "id": "xyz3",
                    "name": "xyz3"
                }
            ],
            [
                {
                    "id": "xyz1",
                    "name": "xyz1"
                }, {
                    "id": "xyz3",
                    "name": "xyz3"
                }, {
                    "id": "xyz5",
                    "name": "xyz5"
                }
            ]
        ]
    }
}

"elements.minorElements" - это массив массива.

Как написать агрегацию mon go удалить объекты из "elements.minorElements", где "id" не в "xyz1" и "xyz2"?

Ожидаемый результат:

{
    "_id": "123",
    "name": "ABC",
    "elements": {
        "_id": "123",
        "minorElements": [
            [{
                    "id": "xyz1",
                    "name": "xyz1"
                }, {
                    "id": "xyz2",
                    "name": "xyz2"
                }
            ],
            [{
                    "id": "xyz1",
                    "name": "xyz1"
                }
            ]
        ]
    }
}

образец полезной нагрузки https://mongoplayground.net/p/9RjC6GzSQDQ

Ответы [ 2 ]

2 голосов
/ 03 февраля 2020

Вам нужно $ map для внешнего массива и $ filter для внутреннего массива:

db.collection.aggregate([
    {
        $addFields: {
            "elements.minorElements": {
                $map: {
                    input: "$elements.minorElements",
                    as: "me",
                    in: {
                        $filter: {
                            input: "$$me",
                            cond: {
                                $in: [ "$$this.id", [ "xyz1", "xyz2" ] ]
                            } 
                        }
                    }
                }
            }
        }
    }
])

Mon go Playground

1 голос
/ 03 февраля 2020

2 замечания: Во-первых,

для удаления объектов из "elements.minorElements", где "id" отсутствует в "xyz1" и "xyz2"

=> просто означает, что вам нужно сохранить (спроектировать) элементы, где id равен «xyz1» или «xyz2» (или id в [«xyz1», «xyz2»])

Second,

Как вы заметили, elements.minorElements - это массив массивов. Поэтому, когда вы применяете свой оператор $ filter, вы пытаетесь применить его к массиву .

Совет - применить оператор $ map для первого уровня массива, а затем Оператор $ fiter для каждого элемента $ map.

Вот запрос:

db.collection.aggregate([
  {
    "$project": {
      "elements.minorElements": {
        "$map": {
          "input": "$elements.minorElements",
          "as": "item",
          "in": {
            $filter: {
              input: "$$item",
              as: "subItem",
              cond: {
                $in: [
                  "$$subItem.id",
                  [
                    "xyz1",
                    "xyz2"
                  ]
                ]
              }
            }
          },

        }
      }
    }
  }
])

Вы можете проверить его здесь.

...