sql >> Databasteknik >  >> NoSQL >> MongoDB

SailsJS &MongoDB Aggregation ramverk problem med anpassade frågor

Din första förfrågan var på rätt väg. Då använde du fel 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);
        }
})

Naturligtvis $size operatören där kräver att du behöver en MongoDB 2.6 eller senare version, vilket du förmodligen borde göra vid det här laget, men du kan fortfarande göra samma sak utan operatören för att mäta arraylä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 samma sak genom att räkna medlemmarna i arrayen, men istället skulle du behöva $unwind arrayelementen för att räkna dem. Så det kan fortfarande göras men är inte lika effektivt.

Dessutom måste du hantera de fall där arrayen verkligen är tom men närvarande på grund av hur $unwind behandlar en tom array [] . Om det inte fanns något innehåll skulle dokumentet som innehöll ett sådant element tas bort från resultaten. På liknande sätt skulle du behöva använda $ ifNull för att ställa in en array där dokumentet inte ens innehöll ett element för $unwind för att inte resultera i ett fel.

Om du verkligen tänker göra den här typen av frågor regelbundet, bör du behålla ett "totalt" fält i dokumentet istället för att försöka beräkna det först. Använd $inc operatör tillsammans med operationer som $push och $pull för att hålla koll på den aktuella arraylängden.

Det går lite bort från den allmänna Waterline-filosofin, men du har redan introducerat inbyggda aggregeringsoperationer och det är inte så mycket jobbigt att inse att du får bättre prestanda av att använda inbyggda operationer i andra områden också.

Så med dokument som dessa:

{
  "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 exakt de resultat du vill ha i varje fall:

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



  1. Vilken är den bästa datastrukturen för att lagra denna data på mongoDB?

  2. mongodb kan inte göra transaktioner i Go och fick alltid Kan inte skapa namnutrymme i transaktion med flera dokument

  3. Tidsstämpel till datum i php och mongodb

  4. Kan Meteor korrekt hantera data som uppdateras externt direkt till MongoDB-databasen?