sql >> Database >  >> NoSQL >> MongoDB

Dynamic Sticky Sorting in Mongo voor een eenvoudige waarde of lijst

Ik kan je fout niet reproduceren, maar je hebt een paar "typefouten" in je vraag, dus ik weet niet zeker wat je eigenlijk hebt.

Maar aangenomen dat u daadwerkelijk met MongoDB 2.6 of hoger werkt, wilt u waarschijnlijk de $setIntersection of $setIsSubset operators in plaats van $setUnion . Die operatoren impliceren dat de inhoud van de array waarmee ze worden vergeleken "overeenkomstig" is, waarbij $setUnion combineert gewoon de geleverde array met de bestaande:

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

In eerdere versies waar u deze set-operators niet hebt je gebruikt gewoon $unwind om met de array te werken, en hetzelfde soort $cond operatie als voorheen binnen een $group om alles weer bij elkaar te brengen:

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
    }}
])

Maar je was zeker op de goede weg. Kies gewoon de juiste instelling of een andere methode om precies aan uw behoefte te voldoen.

Of omdat je je manier hebt gepost om te krijgen wat je wilt, is dit een betere manier om dat soort "geordende overeenkomsten" te schrijven:

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
    }}
])

En dat zou prioriteit geven aan documenten met "kantoren" die "FL" bevatten boven "SC" en dus boven alle andere, en de bewerking binnen één enkel veld uitvoeren. Dat zou ook heel gemakkelijk moeten zijn voor mensen om te zien hoe ze dat in het formulier kunnen abstraheren met behulp van $unwind in eerdere versies zonder de set-operators. Waar u eenvoudigweg de hogere "gewichtswaarde" opgeeft voor de items die u bovenaan wilt hebben door de $cond verklaringen.



  1. MongoDB geaggregeerde tijdreeksen

  2. Waarom is alert gedefinieerd, en twee regels later is het niet (Meteor)?

  3. Data.model.updateItem is geen functie TypeError:Data.model.updateItem is geen functie

  4. MongoDB deleteMany()