【发布时间】:2020-05-12 18:03:17
【问题描述】:
我有一个具有以下结构的 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")
}
}
为了实现这一点,我参考了以下两个网页来制作聚合和过滤的管道:
How to write bson form of mongo query in golang?
一开始我使用github的mdb.MongoPipeline(pipeline)有问题,所以决定使用github的pipeline格式,以mongo.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: { $$locations.establish: new Date(1580122004573) }, $gtd: { $$locations.establish: new Date(1578826004573) } }
然后当尝试通过测试不同的管道案例进行调试时,这个管道会导致另一个问题:
...
{"as", "locations"},
{"cond", bson.D{
{"$lte", bson.D{{"$$locations.establish", r.URL.Query()["rangeend"][0]}}},
}},
}},
...
错误是: (InvalidPipelineOperator) 无法识别的表达式“$$locations.establish”
知道为什么会发生这两个错误吗?以及如何解决? 谢谢。
【问题讨论】:
标签: mongodb go filter aggregation