MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Сортиране по максимално поле на масива, възходящо или низходящо

Основният проблем с това, което питате тук, се свежда до факта, че въпросните данни са в "масив" и следователно има някои основни предположения, направени от MongoDB за това как се обработва това.

Ако сте приложили сортиране в "низходящ ред", тогава MongoDB ще направи точно това, което поискате, и ще сортира документите по "най-голямата" стойност на посоченото поле в масива:

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

Но ако вместо това сортирате във „възходящ“ ред, разбира се, обратното е вярно и се взема предвид „най-малката“ стойност.

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

Така че единственият начин да направите това означава да разберете коя е максималната дата от данните в масива и след това да сортирате този резултат. Това основно означава прилагане на .aggregate() , което за meteor е операция от страна на сървъра, за съжаление е нещо подобно:

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

Или в най-добрия случай с MongoDB 3.2, където $max може да се приложи директно към израз на масив:

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

Но всъщност и двете не са толкова страхотни, дори ако подходът MongoDB 3.2 има много по-малко допълнителни разходи от това, което е налично за предишни версии, той все още не е толкова добър, колкото можете да получите по отношение на производителността поради необходимостта от преминаване през данните и работа изведе стойността за сортиране.

Така че занай-добро производителност, "винаги" съхранявайте такива данни, които ще ви трябват "извън" на масива. За това има $max оператор "актуализация", който само ще замени стойност в документа "ако" предоставената стойност е "по-голяма от" съществуващата стойност, която вече е там. т.е.:

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

Това означава, че стойността, която искате, "винаги" ще присъства вече в документа с очакваната стойност, така че просто сега е прост въпрос за сортиране на това поле:

.sort({ "maxDate": 1 })

Така че за моите пари бих прегледал съществуващите данни с някой от .aggregate() налични изрази и използвайте тези резултати, за да актуализирате всеки документ, за да съдържа поле "maxDate". След това променете кодирането на всички допълнения и ревизии на данни от масива, за да приложите този $max "актуализация" при всяка промяна.

Наличието на солидно поле вместо изчисление винаги има много по-смислено, ако го използвате достатъчно често. А поддръжката е доста проста.

Във всеки случай, като се има предвид приложената по-горе примерна дата, която е „по-малка от“ другите налични максимални дати, ще се върне за мен във всички форми:

{
        "_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")
}

Което правилно поставя първия документ в горната част на реда за сортиране, като се има предвид „maxDate“.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. rmongodb:използвайки $или в заявка

  2. Как да оптимизирате производителността на MongoDB

  3. Пагинация на масива mongoDB

  4. Какво се случва с Meteor и Fibers/bindEnvironment()?

  5. Как да проверите дали полето на масива съдържа уникална стойност или друг масив в MongoDB?