Mongodb Dynami c проект в совокупности - PullRequest
2 голосов
/ 30 апреля 2020

У меня есть моя коллекция структур

{ 
  a: 1,
  b: 2,
  c: 3,
  d: 4,
  e: 5,
  allowed: ['a', 'b']
}

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

Я хочу получить с использованием агрегата MongoDB и спроектировать каким-либо образом, что разрешенный массив будет использоваться без вручную перечисляя все поля в $ project

{ $project: { a: 1, b: 1 } }

У меня есть одно решение, такое как использование приведенного ниже проекта в совокупности

  db.getCollection("dummy").aggregate([
      { $match: {} },
      {
        $project: {
          a: {
            $cond: {
              if: { $in: ["a", "$allowed"] },
              then: "$a",
              else: "$$REMOVE",
            },
          },
          b: {
            $cond: {
              if: { $in: ["b", "$allowed"] },
              then: "$b",
              else: "$$REMOVE",
            },
          },
        },
      },
    ]);

, но для этого также требуется перечисление всех полей. Я ищу альтернативное решение, которое проецирует поля в разрешенном массиве без перечисления всех полей вручную в $ project.

1 Ответ

2 голосов
/ 30 апреля 2020

Поскольку вы не знаете, какие поля в ваших документах, вам необходимо преобразовать их в пару k - v, используя $objectToArray, затем используйте $filter, чтобы отфильтровать поля, не входящие в массив $allowed. В конечном итоге используйте $arrayToObject для получения начальной формы.

db.collection.aggregate([
  { $replaceRoot: {
    newRoot: {
      $arrayToObject: {
        $filter: {
          input: { $objectToArray: "$$ROOT" },
          cond: { $in: ["$$this.k", "$allowed"] }
        }
      }
    }
  }}
])

MongoPlayground

...