Агрегация MongoDB: добавить поле из внедренного документа через динамический путь поля c - PullRequest
1 голос
/ 28 февраля 2020

У меня есть конвейер агрегации, и я застрял на сцене. На данный момент у меня есть документ в следующем формате:

{
  _id:ObjectId(5e3d326637df7e4dda73ec22),
  levelName:"Level 1",
  levelNames: {
    "Level 1":"5e567993b6ed4b7b4d2c044d"
    "Level 2":"5e567996a7826d45f836dfa3"
    "Level 3":"5e5679991f515a01c73e9006"
  }
}

, и я хочу добавить сцену $ addField / $ set, которая дает мне значение ID записи в объекте levelNames с ключом, соответствующим свойство levelName документа root.

Я пытался использовать какой-то динамический c путь к полю ($ concat: ["levelNames.", "$ levelName"]), но не повезло Это мой этап $ addField:

/**
 * newField: The new field name.
 * expression: The new field expression.
 */
{
  currentLevelId: {
    $let: {
      vars: {
        levelPath: {
          $concat: ["levelNames.", "$levelName"]
        }
      },
      in: {
        currentLevelId: "$$levelPath"
      }
    }
  }
}

, и результат, который я получаю:

{
  _id:ObjectId(5e3d326637df7e4dda73ec22),
  levelName:"Level 1",
  levelNames: {
    "Level 1":"5e567993b6ed4b7b4d2c044d"
    "Level 2":"5e567996a7826d45f836dfa3"
    "Level 3":"5e5679991f515a01c73e9006"
  }
  currentLevelId: {
    currentLevelId:"levelNames.Level 1"
  }
}

Я пытаюсь получить результат currentLevelId равным "5e567993b6ed4b7b4d2c044d", поэтому мой желаемый результат:

{
  _id:ObjectId(5e3d326637df7e4dda73ec22),
  levelName:"Level 1",
  levelNames: {
    "Level 1":"5e567993b6ed4b7b4d2c044d"
    "Level 2":"5e567996a7826d45f836dfa3"
    "Level 3":"5e5679991f515a01c73e9006"
  },
  currentLevelId: "5e567993b6ed4b7b4d2c044d"
}

Есть ли способ, которым это может быть достигнуто?

Ответы [ 2 ]

3 голосов
/ 28 февраля 2020

Используйте это:

db.collection.aggregate([
   { $set: { data: { $objectToArray: "$levelNames" } } },
   {
      $set: {
         currentLevelId: {
            $arrayElemAt: ["$data.v", { $indexOfArray: ["$data.k", "$levelName"] }]
         }
      }
   },
   { $unset: "data" }
])

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

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

Вот запрос агрегации,

*

db.collection.aggregate([
    {
        $addFields: {
            warehouses: { $objectToArray: "$levelNames" }
        }
    },
    {
        $project: {
            levelName: 1,
            levelNames: 1,
            currentLevelId: {
                $filter: {
                    input: "$warehouses",
                    as: "item",
                    cond: { $eq: ["$$item.k", "$levelName"] }
                }
            },
        }
    },
    { $replaceRoot: { newRoot: { $mergeObjects: ["$$ROOT", { $arrayElemAt: ["$currentLevelId", 0] }] } } },
    {
        $project: {
            currentLevelId: "$v",
            levelName: true,
            levelNames: true,
        }
    }
])

*

...