MongoDB: Получить ассоциированное значение из объекта в массиве массивов - PullRequest
1 голос
/ 27 февраля 2020

В понедельник go У меня есть документы, которые следуют следующему шаблону:

{
 name: "test",
 codes: [
  [
    {
      code: "abc",
      value: 123 
    },
    {
      code: "def",
      value: 456 
    },
  ],
  [
    {
      code: "ghi",
      value: 789 
    },
    {
      code: "jkl",
      value: 012 
    },
  ]
 ]
}

Я использую агрегированный запрос (из-за объединений) и в блоке $project мне нужно вернуть "name" и значение объекта, который имеет код "def", если он существует, и пустую строку, если его нет.

Я не могу просто $unwind кодов и $match, потому что код "def" там не гарантирован.

$filter кажется правильным подходом, поскольку $elemMatch не работает, но для меня не очевидно, как это сделать на вложенном массиве массивов.

1 Ответ

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

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

db.collection.aggregate([
    /** merge all arrays inside codes array into code array */
    {
        $addFields: {
            codes: {
                $reduce: {
                    input: '$codes',
                    initialValue: [],
                    in: { $concatArrays: ["$$value", "$$this"] }
                }
            }
        }
    },
    /** project only needed fields & value will be either def value or '', 
     * if 'def' exists in any doc then we're check index of it to get value of that particular object using arrayElemAt */
    {
        $project: {
            _id:0, name: 1, value:
            {
                $cond: [{ $in: ["def", '$codes.code'] }, { $arrayElemAt: ['$codes.value', { $indexOfArray: ["$codes.code", 'def'] }] }, '']
            }
        }
    }])

Тест: MongoDB-Playground

...