Основният проблем с това, което питате тук, се свежда до факта, че въпросните данни са в "масив" и следователно има някои основни предположения, направени от 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“.