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

Řazení podle maximálního pole pole, vzestupně nebo sestupně

Základní problém s tím, na co se zde ptáte, spočívá ve skutečnosti, že dotyčná data jsou v rámci „pole“, a proto existují některé základní předpoklady vytvořené společností MongoDB ohledně toho, jak se s tím zachází.

Pokud jste použili řazení v "sestupném pořadí", MongoDB udělá přesně to, co požadujete, a seřadí dokumenty podle "největší" hodnoty zadaného pole v poli:

.sort({ "revisions.created": -1 ))

Ale pokud místo toho třídíte ve "vzestupném" pořadí, pak je to samozřejmě obráceně a bere se v úvahu "nejmenší" hodnota.

.sort({ "revisions.created": 1 })

Takže jediný způsob, jak to udělat, znamená zjistit, které je maximální datum z dat v poli, a pak seřadit podle tohoto výsledku. To v podstatě znamená použití .aggregate() , což je pro meteor operace na straně serveru, bohužel asi takto:

Collection.aggregate([
    { "$unwind": "$revisions" },
    { "$group": {
        "_id": "$_id",
        "name": { "$first": "$name" },
        "revisions": { "$push": "$revisions" },
        "number": { "$first": "$number" }
        "maxDate": { "$max": "$revisions.created" }
    }},
    { "$sort": { "maxDate": 1 }
])

Nebo v nejlepším případě s MongoDB 3.2, kde $max lze použít přímo na výraz pole:

Collection.aggregate([
    { "$project": {
        "name": 1,
        "revisions": 1,
        "number": 1,
        "maxDate": {
            "$max": {
                "$map": {
                    "input": "$revisions",
                    "as": "el",
                    "in": "$$el.created"
                }
            }
        }
    }},
    { "$sort": { "maxDate": 1 } }
])

Ale ve skutečnosti oba nejsou tak skvělé, i když přístup MongoDB 3.2 má mnohem menší režii než to, co je k dispozici v předchozích verzích, stále to není tak dobré, jak můžete získat, pokud jde o výkon, kvůli nutnosti předávat data a pracovat. mimo hodnotu, podle které se má třídit.

Takže nejlepší výkon, „vždy“ uchovávejte taková data, která budete potřebovat, „mimo“ pole. K tomu existuje $max operátor "aktualizace", který pouze nahradí hodnotu v dokumentu, "pokud" je zadaná hodnota "větší než" existující hodnota, která již existuje. tj.:

Collection.update(
    { "_id": "qTF8kEphNoB3eTNRA" },
    { 
        "$push": {
            "revisions": { "created": new Date("2016-02-01") }            
        },
        "$max": { "maxDate": new Date("2016-02-01") }
    }
)

To znamená, že požadovaná hodnota bude „vždy“ již přítomna v dokumentu s očekávanou hodnotou, takže je nyní jednoduchá záležitost řazení v tomto poli:

.sort({ "maxDate": 1 })

Takže za své peníze bych prošel existující data pomocí některého z .aggregate() dostupné výpisy a pomocí těchto výsledků aktualizujte každý dokument tak, aby obsahoval pole „maxDate“. Potom změňte kódování všech dodatků a revizí dat pole, aby se použilo $max "aktualizovat" při každé změně.

Mít pevné pole místo výpočtu má vždy mnohem větší smysl, pokud jej používáte dostatečně často. A údržba je docela jednoduchá.

V každém případě, vzhledem k výše použitému příkladu data, které je „menší než“ ostatní přítomná maximální data, by se mi vrátilo ve všech formách:

{
        "_id" : "5xF9iDTj3reLDKNHh",
        "name" : "Lorem ipsum",
        "revisions" : [
                {
                        "number" : 0,
                        "comment" : "Dolor sit amet",
                        "created" : ISODate("2016-02-11T01:22:45.588Z")
                }
        ],
        "number" : 1,
        "maxDate" : ISODate("2016-02-11T01:22:45.588Z")
}
{
        "_id" : "qTF8kEphNoB3eTNRA",
        "name" : "Consecitur quinam",
        "revisions" : [
                {
                        "comment" : "Hoste ad poderiquem",
                        "number" : 1,
                        "created" : ISODate("2016-02-11T23:25:46.033Z")
                },
                {
                        "number" : 0,
                        "comment" : "Fagor questibilus",
                        "created" : ISODate("2016-02-11T01:22:45.588Z")
                },
                {
                        "created" : ISODate("2016-02-01T00:00:00Z")
                }
        ],
        "number" : 2,
        "maxDate" : ISODate("2016-02-11T23:25:46.033Z")
}

Což správně umístí první dokument na začátek pořadí řazení s ohledem na "maxDate".




  1. Oblast oznámení a zpráv pomocí Redis

  2. python-rq worker se automaticky zavře

  3. Myšlenky MongoDB a PostgreSQL

  4. Úvahy o správě MongoDB