Фильтрация по значениям вложенных массивов / объектов (на разных уровнях) и $ project по сопоставленным группам (на определенном уровне c) - MongoDB Aggregate - PullRequest
0 голосов
/ 12 апреля 2020

Учитывая, что у меня есть следующая коллекция (игнорируя документы _id):

Коллекция

[
  {
    "Id": "1",
    "Level2": [
      {
        "Id": "1.1",
        "Level3": [
          {
            "Id": "1.1.1",
            "Level4": [
              {
                "Id": "1.1.1.1",
                "Status": "a"
              },
              {
                "Id": "1.1.1.2",
                "Status": "b"
              }
            ]
          },
          {
            "Id": "1.1.2",
            "Level4": [
              {
                "Id": "1.1.2.1",
                "Status": "a"
              },
              {
                "Id": "1.1.2.2",
                "Status": "c"
              }
            ]
          },
          {
            "Id": "1.1.3",
            "Level4": [
              {
                "Id": "1.1.3.1",
                "Status": "c"
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "Id": "2",
    "Level2": [
      {
        "Id": "2.1",
        "Level3": [
          {
            "Id": "2.1.1",
            "Level4": [
              {
                "Id": "2.1.1.1",
                "Status": "a"
              }
            ]
          }
        ]
      }
    ]
  }
]

Условия

Я хочу запросить это такие как:

  • Level2.Id: "1.1"
  • Level2.Level3.Level4.Status $in ["a", "b"]

$project должен:

  • Группа Level2.Level3.Level4 соответствует Level2.Level3
  • Не должно включать Level2.Level3, если это пустой массив

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

Результат 1

[
  {
    "Id": "1.1.1",
    "Level4": [
      {
        "Id": "1.1.1.1",
        "Status": "a"
      },
      {
        "Id": "1.1.1.2",
        "Status": "b"
      }
    ]
  },
  {
    "Id": "1.1.2",
    "Level4": [
      {
        "Id": "1.1.2.1",
        "Status": "a"
      }
    ]
  }
]

Обратите внимание, что если текущий Level2.Id: "2.1" имеет значение "1.1", вместо этого результат должен быть (совпадения в разных документах) :

Результат 2

[
  {
    "Id": "1.1.1",
    "Level4": [
      {
        "Id": "1.1.1.1",
        "Status": "a"
      },
      {
        "Id": "1.1.1.2",
        "Status": "b"
      }
    ]
  },
  {
    "Id": "1.1.2",
    "Level4": [
      {
        "Id": "1.1.2.1",
        "Status": "a"
      }
    ]
  },
  {
    "Id": "2.1.1",
    "Level4": [
      {
        "Id": "2.1.1.1",
        "Status": "a"
      }
    ]
  }
]

Как я могу выполнить sh это с помощью запроса aggregate?

(фильтрация различных уровней и группировка по некоторому уровню)

1 Ответ

0 голосов
/ 13 апреля 2020

Вот ответ (спасибо @Vijay Rajpurohit за помощь в этом):

db.collection.aggregate([
  {
    $unwind: "$Level2"
  },
  {
    $unwind: "$Level2.Level3"
  },
  {
    $unwind: "$Level2.Level3.Level4"
  },
  {
    $match: {
      "Level2.Id": "1.1",
      "Level2.Level3.Level4.Status": {
        $in: [
          "a",
          "b"
        ]
      }
    }
  },
  {
    $group: {
      "_id": "$Level2.Level3.Id",
      "Messages": {
        $push: "$Level2.Level3.Level4"
      }
    }
  }
])

Результат этого запроса:

[
  {
    "Messages": [
      {
        "Id": "1.1.2.1",
        "Status": "a"
      }
    ],
    "_id": "1.1.2"
  },
  {
    "Messages": [
      {
        "Id": "1.1.1.1",
        "Status": "a"
      },
      {
        "Id": "1.1.1.2",
        "Status": "b"
      }
    ],
    "_id": "1.1.1"
  }
]

Пн go Детская площадка

...