Лучшим советом здесь будет «хранить» массивы, отсортированные в первую очередь. Скорее всего, они, вероятно, уже считают, что любая операция $push
(или даже если вы использовали .push()
) на самом деле просто «добавит» к массиву, так что последний элемент «последний» в любом случае.
Так что, если вы на самом деле не «меняете» свойства "date"
после того, как создали, то «последняя дата» всегда «последний» элемент в любом случае. В этом случае, просто $slice
записи:
Data.find({ "hid": "testhid" }).select({
"sensors": { "$slice": -1 },
"actuators": { "$slice": -1 },
"status": { "$slice": -1 }
}).exec(function(err,data) {
]);
«Если», какой-то причине вы на самом деле не удалось сохранить другим способом или изменили "date"
свойства, чтобы они последние уже не «последний», то это вероятно, хорошая идея, чтобы все будущие обновления использовали модификатор $sort
с $push
. Это может «гарантировать», что дополнения к массиву последовательно сортируются. Вы можете даже изменить всю коллекцию в одном простом утверждении:
Date.update(
{},
{
"$push": {
"sensors": { "$each": [], "$sort": { "date": 1 } },
"actuators": { "$each": [], "$sort": { "date": 1 } },
"status": { "$each": [], "$sort": { "date": 1 } }
}
},
{ "multi": true },
function(err,num) {
}
)
В этом одном заявлении, каждый документ в коллекции того, каждый массив упомянутые повторно сортируется, что «последней датой» является «последним» запись для каждого массива. Это означает, что вышеупомянутое использование $slice
прекрасно.
Теперь «Если», абсолютно ничего из этого не возможно для вашего случая, и вы на самом деле есть какая-то причина, почему элементы массива не должны быть обычно хранятся в "date"
порядке, а затем (и только действительно тогда) должны вы прибегать к использованию .aggregate()
для того, чтобы в результатах:
Data.aggregate(
[
{ "$match": { "hid": "testhid" } },
{ "$unwind": "$sensors" },
{ "$sort": { "_id": 1, "sensors.date": -1 } },
{ "$group": {
"_id": "$_id",
"sensors": { "$first": "$sensors" },
"actuators": { "$first": "$actuators" },
"status": { "$first": "$status" },
"updated": { "$first": "$updated" },
"created": { "$first": "$created" }
}},
{ "$unwind": "$actuators" },
{ "$sort": { "_id": 1, "actuators.date": -1 } },
{ "$group": {
"_id": "$_id",
"sensors": { "$first": "$sensors" },
"actuators": { "$first": "$actuators" },
"status": { "$first": "$status" },
"updated": { "$first": "$updated" },
"created": { "$first": "$created" }
}},
{ "$unwind": "$status" },
{ "$sort": { "_id": 1, "status.date": -1 } },
{ "$group": {
"_id": "$_id",
"sensors": { "$first": "$sensors" },
"actuators": { "$first": "$actuators" },
"status": { "$first": "$status" },
"updated": { "$first": "$updated" },
"created": { "$first": "$created" }
}}
],
function(err,data) {
}
)
реальность есть то, что MongoDB не имеет возможности «инлайн рода» содержимое массива в возврате из любого оператора трубопровода запроса или агрегации. Вы можете сделать это только с помощью обработки $unwind
, используя $sort
и, наконец, $group
, используя $first
, чтобы эффективно получить один элемент из отсортированного массива.
Для этого вам нужно сделать «per» массив, так как процесс $unwind
создает отдельные документы для каждого элемента массива. Вы «могли бы» сделать все это в один присест, как:
Data.aggregate(
[
{ "$match": { "hid": "testhid" } },
{ "$unwind": "$sensors" },
{ "$unwind": "$actuators" },
{ "$unwind": "$status" }
{ "$sort": {
"_id": 1,
"sensors.date": -1,
"actuators.date": -1,
"actuators.status": -1
}},
{ "$group": {
"_id": "$_id",
"sensors": { "$first": "$sensors" },
"actuators": { "$first": "$actuators" },
"status": { "$first": "$status" },
"updated": { "$first": "$updated" },
"created": { "$first": "$created" }
}}
],
function(err,data) {
}
)
Но это на самом деле не так много улучшений на другой процесс со всеми вещами считаются.
реальный урок здесь должен быть «сохранить массив отсортирован» и затем делать операцию по $slice
последний пункт является очень простой процесс.
Можете ли вы разместить образец данных (тестовые документы) – Saleem
Вы хотите отсортировать его по дате регистрации не только по дате регистрации, но и по дате размещения? Вы можете разматывать несколько раз, но не один раз несколько массивов. Это должно работать в одном запросе. – Clijsters