sql >> Database >  >> NoSQL >> MongoDB

SailsJS &MongoDB Aggregation framework-problemen met aangepaste query's

Uw eerste vraag was op het goede spoor, u gebruikte de verkeerde pijpleidingoperator.

Artist.native(function(err,collection) {

    collection.aggregate(
        [
            { "$project": {
                "_id": 1,
                "name": 1,
                "total": { "$size": "$dubs" }
            }}
        ],
        function(err,result) {
          if (err) return res.serverError(err);
          console.log(result);
        }
})

Natuurlijk de $size operator daar vereist dat je een MongoDB 2.6 of hogere versie nodig hebt, wat je nu waarschijnlijk zou moeten doen, maar je kunt nog steeds hetzelfde doen zonder de operator voor het meten van de arraylengte:

Artist.native(function(err,collection) {

    collection.aggregate(
        [
            { "$project": {
                "_id": 1,
                "name": 1,
                "dubs": {
                    "$cond": [
                       { "$eq": [ "$dubs", [] ] },
                       [0],
                       "$dubs"
                    ]
                }
            }},
            { "$unwind": "$dubs" },
            { "$group": {
                "_id": "$_id",
                "name": { "$first": "$name" },
                "total": { 
                    "$sum": {
                        "$cond": [
                            { "$eq": [ "$dubs", 0 ] },
                            0,
                            1
                        ]
                    }
                }
            }}
        ],
        function(err,result) {
          if (err) return res.serverError(err);
          console.log(result);
        }
})

Dat doet hetzelfde door de leden van de array te tellen, maar in plaats daarvan moet je $unwind de array-elementen om ze te tellen. Het kan dus nog steeds worden gedaan, maar is niet zo efficiënt.

Bovendien moet u de gevallen behandelen waarin de array echt leeg is maar aanwezig is vanwege de manier waarop $unwind behandelt een lege array [] . Als er geen inhoud was, zou het document dat een dergelijk element bevatte uit de resultaten worden verwijderd. Op een vergelijkbare manier zou u $ifNull om een ​​array in te stellen waarin het document niet eens een element bevat voor $unwind om niet tot een fout te leiden.

Als u van plan bent dit soort zoekopdrachten regelmatig uit te voeren, moet u een "totaal"-veld in het document behouden in plaats van het eerst te berekenen. Gebruik de $inc operator samen met bewerkingen zoals $push en $pull om de huidige arraylengte bij te houden.

Dat wijkt een beetje af van de algemene Waterline-filosofie, maar je hebt al native aggregatiebewerkingen geïntroduceerd en het is niet zo moeilijk om te beseffen dat je ook betere prestaties krijgt door native bewerkingen in andere gebieden te gebruiken.

Dus met documenten als deze:

{
  "dubs": [{},{},{}],
  "name": "The Doors",
  "createdAt": "2014-12-15T15:24:26.216Z",
  "updatedAt": "2014-12-15T15:24:26.216Z",
  "id": "548efd2a436c850000353f4f"
},
{
  "dubs": [],
  "name": "The Beatles",
  "createdAt": "2014-12-15T20:30:33.922Z",
  "updatedAt": "2014-12-15T20:30:33.922Z",
  "id": "548f44e90630d50000e2d61d"
}

U krijgt in elk geval precies de resultaten die u wilt:

{
    "_id" : ObjectId("5494b79d7e22da84d53c8760"),
    "name" : "The Doors",
    "total" : 3
},
{
    "_id" : ObjectId("5494b79d7e22da84d53c8761"),
    "name" : "The Beatles",
    "total" : 0
}



  1. Hoe een update-query in mongodb te schrijven voor diep geneste array?

  2. Bulksleutels maken in Redis - ServiceStack C#

  3. mongodb - maak een document als het niet bestaat, anders push naar array

  4. Een verzameling initialiseren in Dockerized Mongo DB