MongoDB - получить вложенные документы произвольной глубины и структуры объекта

У меня есть коллекция с объектами различной случайной структуры/глубины. Внутри них есть один объект, который я хочу получить в качестве результатов, у которого есть определенная пара ключ/значение, которую я могу использовать для их поиска.

Пример из моей коллекции:

{
    "_id": ObjectId("123"),
    "someKey": "blue",
    "children": [
        {
            "foo": "bar",
            "anotherKey": "anotherValue",
            "whateverA": 111
        }
    ]
}
{
    "_id": ObjectId("456"),
    "blahKey": "dog",
    "children": [
        {
            "anotherRandom": "randomValue",
            "children": [
                {
                    "moreRandom": "stuffValue",
                    "children": [
                        {
                            "foo": "bar",
                            "animalKey": "legsValue",
                            "whateverB": 222
                        }
                    ]
                }
            ]
        }
    ]
}

Я хотел бы найти вложенные документы, содержащие «foo: bar», и получить результат, который выглядит следующим образом:

{
    "foo": "bar",
    "anotherKey": "anotherValue",
    "whateverA": 111
}
{
    "foo": "bar",
    "animalKey": "legsValue",
    "whateverB": 222
}

Затем я могу разбить результаты на страницы. Возможно ли это вообще в MongoDB 5?

Спасибо.

См. это

nimrod serok 09.05.2022 16:58
Использование JavaScript и MongoDB
Использование JavaScript и MongoDB
Сегодня я собираюсь вкратце рассказать о прототипах в JavaScript, а также представить и объяснить вам работу с базой данных MongoDB.
1
1
18
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если мы используем решение @rickhg12hs

Вы можете сделать что-то вроде:

db.collection.aggregate([
  {
    $addFields: {
      res: {
        $function: {
                 body: "function drill(t, n) {if (n.length > 0){for (let elem of n){if (elem['foo'] && elem['foo'] === 'bar'){t.push(elem);}else {drill(t, elem.children)}}}return t}",
          args: [
            [],
            "$children"
          ],
          lang: "js"
        }
      }
    }
  },
  {
    $project: {
      res: {$arrayElemAt: ["$res", 0]},
      _id: 0
    }
  },
  {
    $replaceRoot: {newRoot: "$res"}
  }
])

Как видите, на примере этой детской площадки.

Мы можем использовать $function для рекурсивного поиска этого ключа с именем foo и возврата объекта, который его содержит.

Редактировать по вопросу в комментарии:

Вы можете использовать свой код, чтобы манипулировать им в соответствии с вашими потребностями: например в js:

const key = 'foo';
const val = 'bar';
const body = `function drill(t, n) {if (n.length > 0){for (let elem of n){if (elem[${key}] && elem[${key}] === ${val}){t.push(elem);}else {drill(t, elem.children)}}}return t}`;


db.collection.aggregate([
  {
    $addFields: {res: {$function: {body, args: [[], "$children"], lang: "js"}}}
  },
  {
    $project: {
      res: {$arrayElemAt: ["$res", 0]}, _id: 0}
  },
  {
    $replaceRoot: {newRoot: "$res"}
  }
])

У меня есть один быстрый вопрос относительно приведенного выше кода: - Как мне включить мои параметры поиска db.collection.find( { ... } ) в приведенную выше команду агрегирования? Спасибо.

Jimba 10.05.2022 12:09

Ваш запрос является json до тех пор, пока он не будет выполнен. Вы можете отредактировать это json в своем коде в соответствии с вашими потребностями, прежде чем выполнять запрос.

nimrod serok 10.05.2022 12:13

Обновлен ответ, чтобы содержать это.

nimrod serok 10.05.2022 12:22

Другие вопросы по теме

Похожие вопросы

Когда добавляется новое изображение, старое изображение автоматически заменяется в nodejs, как исправить
Приложение-напоминание С# (Mongodb): как отфильтровать данные из mongodb и сравнить их специально по дате, времени и временному интервалу и дать небольшое окно сообщения
Я получаю такую ​​​​проблему: Uncaught (в обещании) SyntaxError: Неожиданный конец ввода JSON
Группировка уникальных номеров Monngodb
Обновление MongoDB изменить/преобразовать массив со строковыми элементами в массив с элементами объекта, используя существующее/текущее значение в этом объекте
ValidationError: Ошибка проверки пользователя: пароль: требуется путь `пароль`, электронная почта: требуется путь `электронная почта`
Как я могу удалить весь объект из массива по истечении срока его действия в мангусте?
Политика CORS: нет «Access-Control-Allow-Origin»
Mongodb-express не будет компоноваться с docker-compose.yaml
Как отфильтровать результат $lookup в mongodb