Как получить пятерку самых быстрых путевых скоростей с помощью mongodb
Итак, я импортировал эти данные из Excel и хочу найти пять самых быстрых скоростей. Я попытался использовать агрегатную функцию, но было возвращено 0.
db.planes.aggregate({
$group : {
_id : "$msg_dummy",
fastest : {$max : "$ground_speed"}
}
})
{ "_id" : "MSG", "fastest" : "" }
и только один распечатан. Мне нужна пятерка лучших. Вот некоторые данные
{ "_id" : ObjectId("58076dffa85331269df16994"), "msg_dummy" : "MSG", "msg_type" : 4, "flight_id" : 680, "aircraft_id" : "A1C8EB", "date" : 20131213, "time" : 214224, "latitude" : "", "longitude" : 306, "altitude" : 133, "ground_speed" : -512, "heading" : "", "dummy1" : "" }
{ "_id" : ObjectId("58076dffa85331269df16995"), "msg_dummy" : "MSG", "msg_type" : 4, "flight_id" : 680, "aircraft_id" : "A1C8EB", "date" : 20131213, "time" : 214223, "latitude" : "", "longitude" : 307, "altitude" : 133, "ground_speed" : -512, "heading" : "", "dummy1" : "" }
{ "_id" : ObjectId("58076dffa85331269df16996"), "msg_dummy" : "MSG", "msg_type" : 1, "flight_id" : 680, "aircraft_id" : "A1C8EB", "date" : 20131213, "time" : 214223, "latitude" : "", "longitude" : "", "altitude" : "", "ground_speed" : "" }
{ "_id" : ObjectId("58076dffa85331269df16997"), "msg_dummy" : "MSG", "msg_type" : 4, "flight_id" : 680, "aircraft_id" : "A1C8EB", "date" : 20131213, "time" : 214223, "latitude" : "", "longitude" : 307, "altitude" : 133, "ground_speed" : -512, "heading" : "", "dummy1" : "" }
{ "_id" : ObjectId("58076dffa85331269df16998"), "msg_dummy" : "MSG", "msg_type" : 1, "flight_id" : "AAL1538", "aircraft_id" : "ABFEFD", "date" : 20131213, "time" : 214224, "latitude" : "", "longitude" : "", "altitude" : "", "ground_speed" : "" }
{ "_id" : ObjectId("58076dffa85331269df16999"), "msg_dummy" : "MSG", "msg_type" : 4, "flight_id" : "AAL1538", "aircraft_id" : "ABFEFD", "date" : 20131213, "time" : 214224, "latitude" : "", "longitude" : 298, "altitude" : 123, "ground_speed" : 64, "heading" : "", "dummy1" : "" }
{ "_id" : ObjectId("58076dffa85331269df1699a"), "msg_dummy" : "MSG", "msg_type" : 4, "flight_id" : 680, "aircraft_id" : "A1C8EB", "date" : 20131213, "time" : 214224, "latitude" : "", "longitude" : 306, "altitude" : 133, "ground_speed" : -512, "heading" : "", "dummy1" : "" }
{ "_id" : ObjectId("58076dffa85331269df1699b"), "msg_dummy" : "MSG", "msg_type" : 1, "flight_id" : "NKS355", "aircraft_id" : "A67CA6", "date" : 20131213, "time" : 214225, "latitude" : "", "longitude" : "", "altitude" : "", "ground_speed" : "" }
{ "_id" : ObjectId("58076dffa85331269df1699c"), "msg_dummy" : "MSG", "msg_type" : 3, "flight_id" : 680, "aircraft_id" : "A1C8EB", "date" : 20131213, "time" : 214225, "latitude" : 28.64559, "longitude" : -81.57871, "altitude" : 10100, "ground_speed" : 306, "heading" : 133, "dummy1" : -512, "dummy2" : "", "field13" : "" }
{ "_id" : ObjectId("58076dffa85331269df1699d"), "msg_dummy" : "MSG", "msg_type" : 3, "flight_id" : 680, "aircraft_id" : "A1C8EB", "date" : 20131213, "time" : 214225, "latitude" : 28.64517, "longitude" : -81.57823, "altitude" : 10100, "ground_speed" : 306, "heading" : 133, "dummy1" : -512, "dummy2" : "", "field13" : "" }
{ "_id" : ObjectId("58076dffa85331269df1699e"), "msg_dummy" : "MSG", "msg_type" : 4, "flight_id" : "AAL1538", "aircraft_id" : "ABFEFD", "date" : 20131213, "time" : 214225, "latitude" : "", "longitude" : 298, "altitude" : 123, "ground_speed" : 64, "heading" : "", "dummy1" : "" }
2 ответа
Поскольку ground_speed
поле имеет смесь числовых и строковых значений (пустая строка), $max
Оператор возвращает максимальное значение, так как он сравнивает и значение, и тип, используя указанный порядок сравнения BSON для значений разных типов.
Вам необходимо отфильтровать документы и сравнить только те, которые имеют числовые значения для ground_speed
:
db.planes.aggregate([
{ "$match": {
"ground_speed": { "$exists": true, "$type": 1 }
} },
{
"$group" : {
"_id" : "$msg_dummy",
"fastest" : { "$max" : "$ground_speed"}
}
}
])
Чтобы ответить на ваш вопрос, чтобы получить 5 лучших скоростей, необходимо заказать документы по ground_speed
поле с использованием $sort
трубопровод, создавая массив с ground_speed
значения в пределах $group
трубопровод с использованием оператора аккумулятора $push
а затем вернуть 5 лучших из массива, используя $project
трубопровод и $slice
оператор.
Следующий пример показывает это:
db.planes.aggregate([
{ "$match": {
"ground_speed": { "$exists": true, "$type": 1 }
} },
{ "$sort": { "ground_speed": -1 } },
{
"$group" : {
"_id" : "$msg_dummy",
"ground_speeds" : { "$push" : "$ground_speed" }
}
},
{
"$project": {
"_id": 0,
"msg_dummy": "$_id",
"top_five_fastest": { "$slice": ["$ground_speeds", 5] },
"ground_speeds": 1
}
}
])
Для версий MongoDB, которые не поддерживают $slice
оператор, в качестве альтернативы вы можете получить топ-5, ограничив количество документов, попадающих в $group
трубопровод с использованием $limit
оператор, и это должно быть размещено после $sort
трубопровод (по заказанным документам):
db.planes.aggregate([
{ "$match": {
"ground_speed": { "$exists": true, "$type": 1 }
} },
{ "$sort": { "ground_speed": -1 } },
{ "$limit": 5 },
{
"$group" : {
"_id" : "$msg_dummy",
"top_five_fastest" : { "$push" : "$ground_speed" }
}
}
])
Вы можете сделать это без использования совокупного запроса.
Попробуйте следующее:
db.planes.find({},{_id:1,ground_speed:1}).sort({ground_speed:-1}).limit(5)