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

Dynamisk Sticky Sortering i Mongo for en simpel værdi eller liste

Kan ikke gengive din fejl, men du har et par "tastefejl" i dit spørgsmål, så jeg kan ikke være sikker på, hvad du rent faktisk har.

Men hvis du antager, at du rent faktisk arbejder med MongoDB 2.6 eller nyere, vil du sandsynligvis have $setIntersection eller $setIsSubset operatører i stedet for $setUnion . Disse operatører antyder "matchende" indhold af det array, de sammenlignes med, hvor $setUnion kombinerer bare det medfølgende array med det eksisterende:

db.people.aggregate([
    { "$project": {
        "first_name": 1,
        "last_name": 1,
        "sticky": { 
            "$size": { 
                "$setIntersection": [ "$offices", [ "FL", "SC" ]] 
            }
        },
        "offices": 1
    }},
    { "$sort": {
        "sticky": -1,
        "last_name": 1
    }}
])

I tidligere versioner, hvor du ikke har disse sætoperatorer du bruger bare $unwind at arbejde med arrayet, og den samme slags $cond drift som før i en $group for at bringe det hele sammen igen:

db.people.aggregate([
    { "$unwind": "$offices" },
    { "$group": {
        "_id": "$_id",
        "first_name": { "$first": "$first_name" },
        "last_name": { "$first": "$last_name",
        "sticky": { "$sum": { "$cond": [
            { "$or": [
                { "$eq": [ "$offices": "FL" ] },
                { "$eq": [ "$offices": "SC" ] },
            ]},
            1,
            0
        ]}},
        "offices": { "$push": "$offices" }
    }},
    { "$sort": {
        "sticky": -1,
        "last_name": 1
    }}
])

Men du var bestemt på rette vej. Vælg blot den rigtige indstillingsfunktion eller anden metode for at få dit præcise behov.

Eller siden du har postet din måde at få det, du ønsker, er en bedre måde at skrive den slags "ordnet matchning" på:

db.people.aggregate([
    { "$project": {
        "first_name": 1,
        "last_name": 1,
        "sticky": { "$cond": [
            { "$anyElementTrue": {
                "$map": {
                    "input": "$offices",
                    "as": "o",
                    "in": { "$eq": [ "$$o", "FL" ] }
                }
            }},
            2,
            { "$cond": [
                { "$anyElementTrue": {
                    "$map": {
                        "input": "$offices",
                        "as": "o",
                        "in": { "$eq": [ "$$o", "SC" ] }
                    }
                }},
                1,
                0
            ]}
        ]},
        "offices": 1
    }},
    { "$sort": {
        "sticky": -1,
        "last_name": 1
    }}
])

Og det ville prioritere dets dokumenter med "kontorer" indeholdende "FL" over "SC" og dermed over alle andre, og udføre operationen inden for et enkelt felt. Det burde også være meget nemt for folk at se, hvordan man abstraherer det til formularen ved hjælp af $unwind i tidligere versioner uden de indstillede operatører. Hvor du blot angiver den højere "vægt" værdi til de varer, du ønsker øverst ved at indlejre $cond udsagn.



  1. 3 måder at droppe et indeks i MongoDB

  2. Mongodb gruppe ved dbref felt

  3. Hvordan dropper eller sletter man en samling i MongoDB?

  4. Find ud af, om en værdi indeholder mindst ét ​​numerisk ciffer i SQL