sql >> Database >  >> NoSQL >> MongoDB

verzamelingsgegevens groeperen op meerdere velden mongodb

Met het aggregatieraamwerk zal het resultaat enigszins verschillen van uw "gewenste" uitvoer, omdat u in plaats van hash-sleutels een array van objecten krijgt met de _id sleutel met een waarde die u groepeert op veld. Bijvoorbeeld, in plaats van

{
    "28-10-2016":{
        "success_count": 10, 
        "failure_count": 10
    },
    "29-10-2016": {
        "success_count": 10, 
        "failure_count": 10
    }
}

je zou een betere structuur hebben zoals

[
    {
        "_id": "28-10-2016",
        "success_count": 10, 
        "failure_count": 10
    },
        "_id": "29-10-2016",
        "success_count": 10, 
        "failure_count": 10
    }
]

Om het bovenstaande resultaat te bereiken, moet u de $cond operator in de $sum bediener van de accumulator. De $cond operator evalueert een logische voorwaarde op basis van het eerste argument (if) en retourneert vervolgens het tweede argument waarbij de evaluatie waar is (then) of het derde argument waar onwaar (anders). Dit converteert de true/false-logica naar 1 en 0 numerieke waarden die worden ingevoerd in $sum respectievelijk:

"success_count": {
    "$sum": {
        "$cond": [ { "$eq": [ "$status", "success" ] }, 1, 0 ]
    }
}

Als resulterende pijplijn moet men de aggregatiebewerking uitvoeren die de $dateToString operator in de _id sleutelexpressie voor de $group pijplijn:

Orders.aggregate([
    {
        "$group": {
            "_id": {
                "$dateToString": { 
                    "format": "%Y-%m-%d", 
                    "date": "$created_at" 
                }
            },
            "success_count": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$status", "success" ] }, 1, 0 ]
                }
            },
            "failure_count": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$status", "failure" ] }, 1, 0 ]
                }
            }
        }
    }
], function (err, orders){
    if (err) throw err;
    console.log(orders);
})

Er is echter een flexibelere en beter presterende aanpak die veel sneller wordt uitgevoerd dan de bovenstaande, waarbij de meest efficiënte gegevensstructuur voor uw aggregatieresultaat bijvoorbeeld het schema volgt:

orders = [
    {
        "_id": "28-10-2016",
        "counts": [
            { "status": "success", "count": 10 },
            { "status": "failure", "count": 10 }
        ]
    },
    {
        "_id": "29-10-2016",
        "counts": [
            { "status": "success", "count": 10 },
            { "status": "failure", "count": 10 }
        ]
    }
]

Overweeg dan om als volgt een alternatieve pijplijn te gebruiken

Orders.aggregate([
    { 
        "$group": {
            "_id": { 
                "date":  {
                    "$dateToString": { 
                        "format": "%Y-%m-%d", 
                        "date": "$created_at" 
                    }
                },
                "status": { "$toLower": "$status" }
            },
            "count": { "$sum": 1 }
        }
    },
    { 
        "$group": {
            "_id": "$_id.date",
            "counts": {
                "$push": {
                    "status": "$_id.status",
                    "count": "$count"
                }
            }
        }
    }
], function (err, orders){
    if (err) throw err;
    console.log(orders);
})



  1. Is Redis slechts een cache?

  2. MongoDB sorteren op kinderen

  3. Snelste manier om 100 miljoen documenten op ID te verwijderen

  4. mongoimport in docker-compose geeft me de foutmelding 'Kan service niet starten'