Динамический ключ в MongoDB

#mongodb #mongodb-query #aggregation-framework

#mongodb #mongodb-запрос #структура агрегации

Вопрос:

Я пытаюсь создать динамическую группу с помощью (с sum agg) в MongoDB. Но не знаю, как исправить синтаксис.

Позволяет отображать 2 документа:

 {
"_id": {"$oid":"5f69f6a360c8479d0908a649"},
"key":"key1",
"data":{
    "key1":"value1",
    "key2":"value2",
    "key3":"value3",
    "key4":"value4"
    },
"count":10
}

{
"_id": {"$oid":"5f69f6a360c8479d0908a649"},
"key":"key2",
"data":{
    "key1":"value5",
    "key2":"value6",
    "key3":"value7",
    "key4":"value8"
    },
"count":15
}
  

С помощью атрибута key я хочу управлять, который является атрибутом groupby .

Псевдозапрос может выглядеть так:

 [{
    $group: {
        _id: {
            '$key': data[$key]
        },
        sum: {
            '$sum': '$count'
        }
    }
}] 
  

Вывод должен выглядеть следующим образом:

 value1 : 10    
value6 : 15
  

Кто-нибудь знает, как это сделать?

Ответ №1:

Я не понимаю цели $sum и $group , в ваших документах нет массивов.

Этот конвейер агрегации дает желаемый результат:

 db.collection.aggregate([
   { $set: { data: { $objectToArray: "$data" } } },
   { $set: { data: { $filter: { input: "$data", cond: { $eq: ["$$this.k", "$key"] } } } } },
   { $set: { data: { k: { $arrayElemAt: ["$data.v", 0] }, v: "$count" } } },
   { $set: { data: { $arrayToObject: "$data" } } },
   { $replaceRoot: { newRoot: { $mergeObjects: ["$$ROOT", "$data"] } } },
   { $unset: ["key", "count", "data"] }
])
  

Ответ №2:

Вы можете попробовать,

  • $reduce введите данные в виде массива, используя $objectToArray условие проверки, если ключ совпадает с ключом данных, затем верните ключ как значение и значение как поле подсчета
  • преобразуйте возвращенный массив объектов ключей и значений в точный объект, используя $arrayToObject
  • замените поле с помощью $replaceWith
 db.collection.aggregate([
  {
    $replaceWith: {
      $arrayToObject: [
        [
          {
            $reduce: {
              input: { $objectToArray: "$data" },
              initialValue: {},
              in: {
                $cond: [
                  { $eq: ["$$this.k", "$key"] },
                  {
                    k: "$$this.v",
                    v: "$count"
                  },
                  "$$value"
                ]
              }
            }
          }
        ]
      ]
    }
  }
])
  

Игровая площадка