MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Tasti dinamici dopo $raggruppa per

Non che penso sia una buona idea e soprattutto perché non vedo alcuna "aggregazione" qui è che dopo il "raggruppamento" per aggiungere a un array si $push in modo simile tutto quel contenuto nell'array in base allo "status" chiave di raggruppamento e poi converti in chiavi di un documento in un $replaceRoot con $arrayToObject :

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

Resi:

{
        "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..."
                }
        ]
}

Potrebbe andare bene SE in realtà hai "aggregato" in anticipo, ma su qualsiasi raccolta di dimensioni pratiche tutto ciò che sta facendo è provare a forzare l'intera raccolta in un unico documento, ed è probabile che infranga il limite BSON di 16 MB, quindi non consiglierei nemmeno di provare questo senza " raggruppamento" qualcos'altro prima di questo passaggio.

Francamente, lo stesso codice seguente fa la stessa cosa, e senza trucchi di aggregazione e nessun problema di limite 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);

O un po' più breve:

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);

Le aggregazioni vengono utilizzate per la "riduzione dei dati" e tutto ciò che sta semplicemente "rimodellando i risultati" senza effettivamente ridurre i dati restituiti dal server viene generalmente gestito meglio nel codice client comunque. Stai ancora restituendo tutti i dati indipendentemente da ciò che fai e l'elaborazione client del cursore ha un sovraccarico notevolmente inferiore. E NESSUNA restrizione.