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

SailsJS &MongoDB Aggregation-rammeproblemer med tilpassede forespørgsler

Din første forespørgsel var på rette vej, da du brugte den forkerte pipeline-operatør.

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

Selvfølgelig er $size operatør der kræver, at du har brug for en MongoDB 2.6 eller nyere version, hvilket du nok burde gøre nu, men du kan stadig gøre det samme uden operatøren til at måle array-længden:

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

Det gør det samme ved at tælle medlemmerne af arrayet, men i stedet skal du $unwind array-elementerne for at tælle dem. Så det kan stadig lade sig gøre, men er ikke så effektivt.

Derudover skal du håndtere de tilfælde, hvor arrayet virkelig er tomt, men til stede på grund af hvordan $unwind behandler et tomt array [] . Hvis der ikke var noget indhold, ville dokumentet, der indeholdt et sådant element, blive fjernet fra resultaterne. På lignende måde skal du bruge $ ifNull at indstille et array, hvor dokumentet ikke engang indeholdt et element for $unwind for ikke at resultere i en fejl.

Virkelig, hvis du har til hensigt at udføre denne form for forespørgsel på regelmæssig basis, så bør du bevare et "total"-felt i dokumentet i stedet for at søge at beregne det først. Brug $inc operatør sammen med operationer såsom $push og $pull for at holde en oversigt over den aktuelle array-længde.

Det bevæger sig lidt væk fra den generelle Waterline-filosofi, men du har allerede introduceret native aggregeringsoperationer, og det er ikke så meget mere besværligt at indse, at du får bedre ydeevne ved at bruge native operationer på andre områder også.

Så med dokumenter som disse:

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

Du får præcis de resultater, du ønsker i hvert enkelt tilfælde:

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



  1. forespørgsel på en samling uden at sende skema i mongoose

  2. C# mongodb driver 2.0 - Hvordan upsert i en bulk operation?

  3. Hvordan installerer jeg mongodb på beaglebone black

  4. BadValue Ugyldig eller ingen bruger-lokalitet angivet. Sørg for, at miljøvariablerne LANG og/eller LC_* er indstillet korrekt