sql >> Databáze >  >> NoSQL >> MongoDB

Dynamické rychlé třídění v Mongo pro jednoduchou hodnotu nebo seznam

Vaši chybu nelze reprodukovat, ale ve své otázce máte několik "překlepů", takže si nejsem jistý, co ve skutečnosti máte.

Ale za předpokladu, že skutečně pracujete s MongoDB 2.6 nebo vyšší, pravděpodobně budete chtít $setIntersection nebo $setIsSubset operátory spíše než $setUnion . Tyto operátory implikují "odpovídající" obsah pole, se kterým jsou porovnávány, kde $setUnion pouze zkombinuje dodané pole se stávajícím:

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

V předchozích verzích, kde nemáte tyto operátory sady právě používáte $unwind pracovat s polem a stejným typem $cond operace jako dříve v rámci $group jak to všechno vrátit dohromady:

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

Ale určitě jsi byl na správné cestě. Stačí si vybrat správnou sadu operací nebo jinou metodu, abyste dosáhli své přesné potřeby.

Nebo protože jste zveřejnili svůj způsob, jak získat to, co chcete, lepší způsob, jak napsat tento druh "objednaného párování" je tento:

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

A tím by byly upřednostněny dokumenty s "kancelářemi" obsahujícími "FL" před "SC" a tedy před všemi ostatními a provádějící operace v rámci jednoho oboru. To by také mělo být pro lidi velmi snadné vidět, jak to abstrahovat do formuláře pomocí $unwind v dřívějších verzích bez nastavených operátorů. Kde jednoduše poskytnete vyšší hodnotu „váhy“ položkám, které chcete nahoře, vložením $cond prohlášení.



  1. Mongoose uložte všechny parametry z těla požadavku

  2. Znovu najít hash podle hodnot polí

  3. Třídění dílčích dokumentů MongoDb Pipeline Aggregation

  4. Analýza dlouhého řetězce dotazu přímo do MongoDB (stejně jako v SQL)