sql >> Database >  >> NoSQL >> MongoDB

sorteer array in query en projecteer alle velden

Aangezien u zich groepeert op het document _id u kunt eenvoudig de velden die u wilt behouden in de groep plaatsen _id . Vervolgens kun je opnieuw vormen met behulp van $project

db.c.aggregate([
    { "$unwind": "$array_to_sort"},
    { "$sort": {"array_to_sort.b":1, "array_to_sort:a": 1}},
    { "$group": { 
        "_id": {
            "_id": "$_id",
            "unknown_field": "$unknown_field"
        },
        "Oarray_to_sort": { "$push":"$array_to_sort"}
    }},
    { "$project": {
        "_id": "$_id._id",
        "unknown_field": "$_id.unknown_field",
        "array_to_sort": "$Oarray_to_sort"
    }}
]);

De andere "truc" daarin is het gebruik van een tijdelijke naam voor de array in de groeperingsfase. Dit is het geval wanneer u $project en de naam wijzigt, krijgt u de velden in de volgorde die is opgegeven in de projectieverklaring. Als u dat niet deed, zou het veld "array_to_sort" niet het laatste veld in de volgorde zijn, omdat het is gekopieerd uit de vorige fase.

Dat is een beoogde optimalisatie in $project , maar als u de bestelling wilt, kunt u dit doen zoals hierboven.

Voor volledig onbekende structuren is er de mapReduce-manier om dingen te doen:

db.c.mapReduce(
    function () {
        this["array_to_sort"].sort(function(a,b) {
            return a.a - b.a || a.b - b.b;
        });

        emit( this._id, this );
    },
    function(){},
    { "out": { "inline": 1 } }
)

Dat heeft natuurlijk een uitvoerformaat dat specifiek is voor mapReduce en daarom niet precies het document dat u had, maar alle velden staan ​​onder "waarden":

{
    "results" : [
            {
                    "_id" : 0,
                    "value" : {
                            "_id" : 0,
                            "some_field" : "a",
                            "array_to_sort" : [
                                    {
                                            "a" : 1,
                                            "b" : 0
                                    },
                                    {
                                            "a" : 3,
                                            "b" : 3
                                    },
                                    {
                                            "a" : 3,
                                            "b" : 4
                                    }
                            ]
                    }
            }
    ],
}

Toekomstige releases (op het moment van schrijven) stellen je in staat om een ​​$$ROOT . te gebruiken variabele in totaal om het document weer te geven:

db.c.aggregate([
    { "$project": {
        "_id": "$$ROOT",
        "array_to_sort": "$array_to_sort"
    }},
    { "$unwind": "$array_to_sort"},
    { "$sort": {"array_to_sort.b":1, "array_to_sort:a": 1}},
    { "$group": { 
        "_id": "$_id",
        "array_to_sort": { "$push":"$array_to_sort"}
    }}
]);

Het heeft dus geen zin om de laatste "project"-fase te gebruiken, omdat u de andere velden in het document niet echt kent. Maar ze zullen allemaal worden opgenomen (inclusief de originele array en volgorde ) binnen de _id veld van het resultaatdocument.




  1. Kaa Java SDK synchroniseert niet met KAA Sandbox MongoDB op AWS

  2. MongoDB Bulkimport met mongoimport uit de Windows-map

  3. Mongo C#-stuurprogramma:BsonValue deserialiseren

  4. Waarom neemt MongoDB zoveel ruimte in beslag?