sql >> Database >  >> NoSQL >> MongoDB

Hoe geneste berichten te groeperen met het MongoDB-aggregatieraamwerk?

De volgende pijplijn zou voor u moeten werken:

var pipeline = [
    {
        "$project": {
            "title": 1, "body": 1, 
            "post_id": { "$ifNull": [ "$_post", "$_id" ] }
        }
    },  
    {
        "$group": {
            "_id": "$post_id",
            "title": { "$first": "$title" },
            "body": { "$first": "$body" },
            "comments": {
                "$push": {
                    "_id": "$_id",
                    "_post": "$post_id",
                    "body": "$body"
                }
            }
        }
    },
    {
        "$project": {
            "title": 1, "body": 1,
            "comments": {
                "$setDifference": [
                    {
                        "$map": {
                            "input": "$comments",
                            "as": "el",
                            "in": {
                                "$cond": [
                                    { "$ne": [ "$$el._id", "$$el._post" ] },
                                    "$$el",
                                    false
                                ]
                            }
                        }
                    },
                    [false]
                ]
            }
        }
    }
];

Post.aggregate(pipeline, function (err, result) {
    if (err) { /* handle error */ };
    console.log(result);
});

De pijplijn is zo gestructureerd dat uw eerste stap, de $project operator stadium, is om het veld post_id . te projecteren om te worden gebruikt als de groep op sleutel in de volgende pijplijnfase. Aangezien uw schema hiërarchisch is, hebt u dit veld nodig voor bovenliggende/root-documenten. De $ifNull operator zal optreden als de samenvoegingsoperator en de vervangingswaarde teruggeven als het veld niet bestaat in de documenten.

De volgende pijplijnstap, de $groep pijplijnfase probeert de gegevens te groeperen om ze te verwerken. De $group pijplijnoperator is vergelijkbaar met de GROUP BY-clausule van de SQL. In SQL kunnen we GROUP BY niet gebruiken, tenzij we een van de aggregatiefuncties gebruiken. Op dezelfde manier moeten we ook een aggregatiefunctie in MongoDB gebruiken. In dit geval heb je de $push operator om de array met opmerkingen te maken. De andere velden worden vervolgens verzameld met behulp van de $first telefoniste.

De laatste stap omvat het aanpassen van de opmerkingenreeks, zodat u het document met de berichtdetails verwijdert, wat zeker niet van het type opmerking is. Dit wordt mogelijk gemaakt door de $setDifference en $map exploitanten. De $map operator creëert in wezen een nieuw arrayveld dat waarden bevat als resultaat van de geëvalueerde logica in een subexpressie voor elk element van een array. De $setDifference operator retourneert vervolgens een set met elementen die in de eerste set voorkomen, maar niet in de tweede set; d.w.z. voert een relatieve aanvulling uit van de tweede set ten opzichte van de eerste. In dit geval retourneert het de laatste opmerkingen array met elementen die niet gerelateerd zijn aan de bovenliggende documenten via de _id eigendom.




  1. Redis pub/sub op rails

  2. MongoDb - Gebruik van een multi-CPU-server voor een zware schrijftoepassing

  3. Lijst met interface-objecten die mongo-stuurprogramma voor java gebruiken

  4. PyMongo $inc heeft problemen