MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Динамични ключове след $group by

Не че мисля, че е добра идея и най-вече защото не виждам никакво "агрегиране" тук е, че след "групиране" за добавяне към масив вие по подобен начин $push цялото това съдържание в масив от "status" ключ за групиране и след това конвертирайте в ключове на документ в $replaceRoot с $arrayToObject :

db.collection.aggregate([
  { "$group": {
    "_id": "$status",
    "data": { "$push": "$$ROOT" }
  }},
  { "$group": {
    "_id": null,
    "data": {
      "$push": {
        "k": "$_id",
        "v": "$data"
      }
    }
  }},
  { "$replaceRoot": {
    "newRoot": { "$arrayToObject": "$data" }
  }}
])

Връща:

{
        "inProgress" : [
                {
                        "_id" : ObjectId("5b18d31a27a37696ec8b5776"),
                        "status" : "inProgress",
                        "description" : "inProgress..."
                }
        ],
        "completed" : [
                {
                        "_id" : ObjectId("5b18d31a27a37696ec8b5773"),
                        "status" : "completed",
                        "description" : "completed..."
                }
        ],
        "pending" : [
                {
                        "_id" : ObjectId("5b18d14cbc83fd271b6a157c"),
                        "status" : "pending",
                        "description" : "You have to complete the challenge..."
                },
                {
                        "_id" : ObjectId("5b18d31a27a37696ec8b5775"),
                        "status" : "pending",
                        "description" : "pending..."
                }
        ]
}

Това може да е наред АКО всъщност "агрегирахте" предварително, но във всяка колекция с практически размер всичко, което правите, е да се опитва да накара цялата колекция в един документ и това вероятно ще наруши ограничението на BSON от 16 MB, така че просто не бих препоръчал дори да опитвате това без " групиране" нещо друго преди тази стъпка.

Честно казано, същият следният код прави същото и без трикове за агрегиране и без проблем с ограничението на BSON:

var obj = {};

// Using forEach as a premise for representing "any" cursor iteration form
db.collection.find().forEach(d => {
  if (!obj.hasOwnProperty(d.status))
    obj[d.status] = [];
  obj[d.status].push(d);
})

printjson(obj);

Или малко по-кратко:

var obj = {};

// Using forEach as a premise for representing "any" cursor iteration form
db.collection.find().forEach(d => 
  obj[d.status] = [ 
    ...(obj.hasOwnProperty(d.status)) ? obj[d.status] : [],
    d
  ]
)

printjson(obj);

Агрегациите се използват за "намаляване на данни" и всичко, което е просто "преоформяне на резултатите", без реално да се намаляват данните, върнати от сървъра, така или иначе обикновено се обработва по-добре в клиентския код. Все още връщате всички данни, независимо какво правите, а клиентската обработка на курсора има значително по-малко излишни разходи. И БЕЗ ограничения.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Вземете броя на отворените връзки в mongoDB с помощта на java

  2. Как да използвате mongoose findOne

  3. Компресиране на индексен префикс в MongoDB 3.0 WiredTiger

  4. MongoDB, премахнете обекта от масива

  5. Mongoose, намерете, върнете конкретни свойства