sql >> Database >  >> NoSQL >> MongoDB

Dynamische toetsen na $groeperen op

Niet dat ik denk dat het een goed idee is en vooral omdat ik hier helemaal geen "aggregatie" zie, is dat na "groeperen" om aan een array toe te voegen, je op dezelfde manier $push al die inhoud in een array met de "status" groeperingssleutel en vervolgens converteren naar sleutels van een document in een $replaceRoot met $arrayToObject :

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

Retourneren:

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

Dat is misschien oké ALS je hebt eigenlijk van tevoren "geaggregeerd", maar bij elke verzameling van praktisch formaat is het enige dat je doet proberen de hele verzameling in een enkel document te forceren, en dat zal waarschijnlijk de BSON-limiet van 16 MB breken, dus ik zou het gewoon niet aanraden om dit zelfs maar te proberen zonder " groeperen" vóór deze stap.

Eerlijk gezegd doet dezelfde volgende code hetzelfde, en zonder aggregatietrucs en geen BSON-limietprobleem:

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

Of iets korter:

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

Aggregaties worden gebruikt voor "gegevensreductie" en alles wat eenvoudigweg "resultaten hervormt" zonder de gegevens die van de server worden geretourneerd daadwerkelijk te verminderen, wordt hoe dan ook meestal beter in clientcode afgehandeld. U retourneert nog steeds alle gegevens, wat u ook doet, en de clientverwerking van de cursor heeft aanzienlijk minder overhead. En GEEN beperkingen.




  1. Te veel open bestanden en zorg ervoor dat index mongo

  2. Redis as Hibernate tweede niveau cache

  3. Waarom is er slechts één verbinding met redis gemaakt in dit gevent-programma?

  4. Ontvang de ingestelde waarde van Redis met RedisTemplate