sql >> Database teknologi >  >> NoSQL >> MongoDB

Sådan sorteres dokumenter baseret på længden af ​​et Array-felt

Hvad du synes at mene her er, at du vil "sortere" dine resultater baseret på "længden" af "svar"-arrayet, snarere end en "egenskab" kaldet "længde", som din syntaks antyder. For en god ordens skyld ville den syntaks være umulig her, da din model er "refereret", hvilket betyder, at de eneste data, der findes i array-feltet i dokumenterne i denne samling, er ObjectId værdierne af disse refererede dokumenter.

Men du kan gøre dette ved at bruge .aggregate() metoden og $size operatør:

Question.aggregate(
    [
        { "$project": {
            "title": 1,
            "content": 1,
            "created": 1,
            "updated": 1,
            "author": 1,
            "answers": 1,
            "length": { "$size": "$answers" }
        }},
        { "$sort": { "length": -1 } },
        { "$limit": 5 }
    ],
    function(err,results) {
        // results in here
    }
)

En aggregeringspipeline fungerer i etaper. For det første er der et $projekt for felterne i resultaterne, hvor du bruger $size for at returnere længden af ​​det angivne array.

Nu er der et felt med "længden", du følger etaperne med $sort og $limit som anvendes som deres egne stadier i en aggregeringspipeline.

En bedre tilgang ville være altid at opretholde længdeegenskaben for dit "svar"-array i dokumentet. Dette gør det nemt at sortere og forespørge på uden andre handlinger. Det er nemt at vedligeholde dette ved at bruge $inc operatør som du $push eller $pull elementer fra arrayet:

Question.findByIdAndUpdate(id,
    {
        "$push": { "answers": answerId },
        "$inc": { "answerLength": 1 } 
    },
    function(err,doc) {

    }
)

Eller omvendt, når du fjerner:

Question.findByIdAndUpdate(id,
    {
        "$pull": { "answers": answerId },
        "$inc": { "answerLength": -1 } 
    },
    function(err,doc) {

    }
)

Selvom du ikke bruger atomoperatorerne, så gælder de samme principper, hvor du opdaterer "længden" efterhånden. Så er det nemt at forespørge med en sortering:

Question.find().sort({ "answerLength": -1 }).limit(5).exec(function(err,result) {

});

Da ejendommen allerede er der i dokumentet.

Så gør det enten med .aggregate() uden ændringer af dine data, eller ændre dine data til altid at inkludere længden som en egenskab, og dine forespørgsler vil være meget hurtige.



  1. MongoDB med java Undtagelse i trådens hoved java.lang.NoClassDefFoundError:org/bson/conversions/Bson

  2. MongoDB jokertegn i nøglen til en forespørgsel

  3. En oversigt over MongoDB og belastningsbalancering

  4. Gruppér og tæl ved hjælp af aggregeringsramme