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

Ordinamento dinamico permanente in Mongo per un semplice valore o elenco

Non riesco a riprodurre il tuo errore, ma hai qualche "errore di battitura" nella tua domanda, quindi non posso essere sicuro di cosa hai effettivamente.

Ma supponendo che tu stia effettivamente lavorando con MongoDB 2.6 o versioni successive, probabilmente vorrai il $setIntersection o $setIsSubset operatori anziché $setUnion . Tali operatori implicano la "corrispondenza" dei contenuti dell'array con cui vengono confrontati, dove $setUnion combina semplicemente l'array fornito con quello esistente:

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

Nelle versioni precedenti in cui non disponi di quegli set operator stai solo usando $unwind per lavorare con l'array e lo stesso tipo di $cond operazione come prima all'interno di un $group per rimettere tutto insieme:

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

Ma di certo eri sulla strada giusta. Basta scegliere l'operazione di impostazione corretta o un altro metodo per ottenere la tua esigenza precisa.

Oppure, dal momento che hai pubblicato il tuo modo per ottenere ciò che desideri, un modo migliore per scrivere quel tipo di "corrispondenza ordinata" è questo:

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

E questo darebbe priorità ai documenti con "uffici" contenenti "FL" su "SC" e quindi su tutti gli altri, e facendo l'operazione all'interno di un unico campo. Dovrebbe anche essere molto facile per le persone vedere come astrarre ciò nel modulo usando $unwind nelle versioni precedenti senza gli operatori di insiemi. Dove fornisci semplicemente il valore di "peso" più alto agli elementi che desideri in alto nidificando il $cond dichiarazioni.