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".