Фильтр запросов по массиву вложенных документов (3 уровня) в mongoDb - PullRequest
2 голосов
/ 27 июня 2019

У меня есть коллекция диаграмм.Каждая диаграмма имеет несколько блоков.И у каждого блока есть несколько портов, которые сами по себе имеют несколько объектов в качестве полей.Пока я могу применять только $filter или $group до уровня 1 для блоков.Я не могу отфильтровать до портов на основании какого-либо условия.

Структура документа: Диаграмма

[
  {
    "_id": "1",
    "blocks": [
      {
        "port": [
          {
            "portType": {
              "function": "input"
            }
          }
        ]
      }
    ]
  }
]

Что я пытаюсь достичь, это получить список всех портов, которые имеютinput как portType.function из коллекции

db.collection.aggregate([{$project:{"blocks.ports":{$filter:{input:"$blocks.ports",as:"ports",cond:{$in:["input","$$ports.portType.function"]}}}}}]);

Ожидаемый результат: list<Ports>, в качестве входных данных которого есть только portType.function.

Фактический результат: Возвращает все документы, имеющиекак минимум один порт в качестве «входа» вместе со всеми другими портами.

Ответы [ 2 ]

0 голосов
/ 27 июня 2019

Если вам нужен список Port объектов, вы должны использовать двойной $unwind stage, затем $match для blocks.port.portType.function и, наконец, извлечь только порты, используя $project stage

db.collection.aggregate([
  {
    "$unwind": "$blocks"
  },
  {
    "$unwind": "$blocks.port"
  },
  {
    "$match": {
      "blocks.port.portType.function": "input"
    }
  },
  {
    $project: {
      _id: 0,
      portType: "$blocks.port.portType",
    }
  }
])

Если ваш Port объект содержит другие поля, которые вы хотите извлечь, например, Foo, вам просто нужно добавить эти поля на этапе $project, например

$project: {
    _id: 0,
    portType: "$blocks.port.portType",
    foo: "$blocks.port.foo"
    ...
}
0 голосов
/ 27 июня 2019

Вы можете просто использовать две $unwind ступени для выравнивания массивов, а затем $match ступень, подобную этой:

db.collection.aggregate([
  {
    "$unwind": "$blocks"
  },
  {
    "$unwind": "$blocks.port"
  },
  {
    "$match": {
      "blocks.port.portType.function": "input"
    }
  }
])

результат:

[
  {
    "_id": "1",
    "blocks": {
      "port": {
        "portType": {
          "function": "input"
        }
      }
    }
  }
]

попробуйте онлайн: mongoplayground.net / p / TOUCkCOSE7D

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...