У меня есть коллекция mongodb со следующей структурой:
{
"_id" : ObjectId("5e2af47006d5b7820876cc34"),
"uuid" : "6ec5245e-d512-4496-995d-9a7d1073ff80",
"beaconid" : "fc775907-f442-43ca-9b86-78fede5f9218",
"locations" : [
{
"longitude" : 464.4,
"latitude" : 34.8,
"establish" : ISODate("2020-01-24T13:43:12.895Z")
},
{
"longitude" : 464.4,
"latitude" : 34.8,
"establish" : ISODate("2020-01-24T13:47:09.066Z")
},
{
"longitude" : 464.4,
"latitude" : 34.8,
"establish" : ISODate("2020-01-24T15:03:02.770Z")
},
{
"longitude" : 464.4,
"latitude" : 34.8,
"establish" : ISODate("2020-01-24T15:23:36.891Z")
}
}
{
......
}
В настоящее время я разрабатываю API для получения всех местоположений в определенном временном диапазоне, используя функции агрегации и фильтрации mongodb в golang .
Например: я хотел бы получить все значения из ISODate ("2020-01-24T13: 45: 00.066Z") в ISODate ("2020-01-24T15: 10: 00.770Z"), которые извлекают только средние два местоположения, выходные данные должны быть следующими:
{
"_id" : ObjectId("5e2af47006d5b7820876cc34"),
"uuid" : "6ec5245e-d512-4496-995d-9a7d1073ff80",
"beaconid" : "fc775907-f442-43ca-9b86-78fede5f9218",
"locations" : [
{
"longitude" : 464.4,
"latitude" : 34.8,
"establish" : ISODate("2020-01-24T13:47:09.066Z")
},
{
"longitude" : 464.4,
"latitude" : 34.8,
"establish" : ISODate("2020-01-24T15:03:02.770Z")
}
}
Для этого я сослался на следующие две веб-страницы для создания конвейера для агрегации и фильтрации:
https://github.com/simagix/mongo-go-examples/blob/5a04bab8b677e7b160dbe4c327f7ac68efb83ba5/examples/aggregate_reduce_test.go
Как записать bson-форму запроса mon go в golang?
Сначала у меня возникли проблемы с использованием mdb.MongoPipeline github (конвейер), поэтому я решил использовать формат конвейера github и использовать его в виде второго ответа переполнения стека mon go .Pipeline {...}
Полученный конвейер становится:
new_pipeline = mongo.Pipeline{
{{"$match", bson.D{
{"beaconID", r.URL.Query()["beaconid"][0]},
}}},
{{"$project", bson.D{
{"locations", bson.D{
{"$filter", bson.D{
{"input", "$locations"},
{"as", "locations"},
{"cond", bson.D{
{"$and", bson.D{
{"$lte", bson.D{{"locations.establish", r.URL.Query()["rangeend"][0]}}},
{"$gtd", bson.D{{"locations.establish", r.URL.Query()["rangebegin"][0]}}},
}},
}},
}},
}},
}}},
{{"$unwind", "$locations"}},
}
opts := options.Aggregate()
cursor, err := collection.Aggregate(context.TODO(), new_pipeline, opts)
Однако, при запуске программы возникает ошибка, которую я не знаю, как ее решить:
(Location15983) У объекта, представляющего выражение, должно быть ровно одно поле: {$ lte: {$$ location.establi sh : новая дата (1580122004573)}, $ gtd: {$$ location.establi sh: новая дата (1578826004573)}}
А затем при попытке отладки путем тестирования различных случаев конвейера этот конвейер вызывает другую проблема:
...
{"as", "locations"},
{"cond", bson.D{
{"$lte", bson.D{{"$$locations.establish", r.URL.Query()["rangeend"][0]}}},
}},
}},
...
Ошибка: (InvalidPipelineOperator) Нераспознанное выражение '$$ location.establi sh'
Есть идеи, почему эти две ошибки происходят? И как это исправить? Спасибо.