sql >> Database >  >> NoSQL >> MongoDB

Hoe te aggregeren met groeperen op en correct sorteren

Er zijn een paar vangsten om te begrijpen.

Wanneer u $group gebruikt de grenzen worden gesorteerd in de volgorde waarin ze zijn ontdekt zonder een begin- of eindstadium $sort operatie. Dus als uw documenten oorspronkelijk in een volgorde als deze stonden:

{ uid: 1, created: ISODate("2014-05-02..."), another_col : "x" },
{ uid: 1, created: ISODate("2014-05-05..."), another_col : "y" },
{ uid: 3, created: ISODate("2014-05-05..."), another_col : "w" },
{ uid: 2, created: ISODate("2014-05-10..."), another_col : "z" },

Gebruik dan gewoon $group zonder een $sort aan het einde van de pijplijn zou u de volgende resultaten opleveren:

{ uid: 1, created: ISODate("2014-05-05..."), another_col : "y" },
{ uid: 3, created: ISODate("2014-05-05..."), another_col : "w" },
{ uid: 2, created: ISODate("2014-05-10..."), another_col : "z" },

Dat is één concept, maar het lijkt erop dat wat u verwacht in resultaten, vereist dat de "laatste andere velden" worden geretourneerd in een gesorteerde volgorde van de uid is wat u zoekt. In dat geval is de manier om uw resultaat te krijgen eigenlijk $sort eerst en gebruik dan de $last operator:

db.mycollection.aggregate([

    // Sorts everything first by _id and created
    { "$sort": { "_id": 1, "created": 1 } },

    // Group with the $last results from each boundary
    { "$group": {
        "_id": "$uid",
        "created": { "$last": "$created" },
        "another_col": { "$last": "$created" }
    }}
])

Of pas de sortering in wezen toe op wat u wilt.

Het verschil tussen $last en $max is dat de laatste de "hoogste" waarde zal kiezen voor het gegeven veld binnen de groepering _id , ongeacht de huidige gesorteerd op ongesorteerde volgorde. Aan de andere kant, $last zal de waarde kiezen die voorkomt in dezelfde "rij" als de "laatste" groepering _id waarde.

Als u de waarden van een array daadwerkelijk wilde sorteren, is de aanpak vergelijkbaar. Als u de arrayleden in de volgorde "aangemaakt" houdt, zou u ook eerst sorteren:

db.mycollection.aggregate([

    // Sorts everything first by _id and created
    { "$sort": { "_id": 1, "created": 1 } },

    // Group with the $last results from each boundary
    { "$group": {
        "_id": "$uid",
        "row": {
            "$push": {
                "created": "$created",
                "another_col": "$another_col"
            }
        }
    }}
])

En de documenten met die velden worden aan de array toegevoegd in de volgorde waarop ze al waren gesorteerd.



  1. MongoDB / Geojson $geokruist problemen

  2. MongoDB $pull-syntaxis

  3. Redis lua-script werkt niet

  4. mongodb sorteer en regex query op een efficiënte manier