这是我的 mongodb 数据库:
"_id" : ObjectId("58808d735ba19c2797f486ca"),
"userid" : ObjectId("58808d735ba19c2797f486c9"),
"history" : [
{
"floorId" : "309cf96f-1812-44f6-8d94-d5ce2b8839be",
"time" : ISODate("2017-01-19T09:57:34.572Z"),
"position" : {
"latitude" : 48.815267598833806,
"longitude" : 2.3630101271630677
},
"pointcoordinates" : {
"pointX" : 503.82333,
"pointY" : 339.00385
}
},
{
"floorId" : "309cf96f-1812-44f6-8d94-d5ce2b8839be",
"time" : ISODate("2017-01-19T09:57:34.574Z"),
"position" : {
"latitude" : 48.815267598833806,
"longitude" : 2.3630101271630677
},
"pointcoordinates" : {
"pointX" : 503.82333,
"pointY" : 339.00385
}
}, ... This array is very huge !
我想从某个日期范围内的“历史记录”中检索一些值。
首先,我需要选择我要访问的“userid”的对象,然后选择“history”。然后获取我知道的日期范围内的值。
我将 Golang 与 mgo.v2 (mongodb) 驱动程序一起使用。
这是我的代码:
id := queryValues.Get("id")
startTime := queryValues.Get("startTime")
endTime := queryValues.Get("endTime")
//Here I get times in forme time.Time
t_startTime, err := time.Parse(time.RFC3339Nano, startTime)
t_endTime, err := time.Parse(time.RFC3339Nano, endTime)
oid := bson.ObjectIdHex(id)
//I select the range of time what I want
selector := bson.M{"history": bson.M{"time": bson.M{"$gte": t_startTime, "$lte": t_endTime}}}
if err := uc.session.DB("TEST").C("history").Find(bson.M{"userid": oid}).Select(selector).All(&history); err != nil {
fmt.Println(err)
SendError(w, "GetHistory", "Error retrieving history")
} else {
spew.Dump(history)
}
我得到一个错误:
Can't canonicalize query: BadValue Unsupported projection option: history: { time: { $gte: new Date(1484819854576), $lte: new Date(1484819854576) } }
有人可以帮忙吗?
最佳答案
您可以在编写代码之前阅读文档。
func (q *Query) Select(selector interface{}) *Query
Select enables selecting which fields should be retrieved for the results found. For example, the following query would only retrieve the name field:
err := collection.Find(nil).Select(bson.M{"name": 1}).One(&result)
Relevant documentation:
https://docs.mongodb.com/v3.2/tutorial/project-fields-from-query-results/#return-the-specified-fields-and-the-id-field-only (link is changed to actual one)
所以您的
Select(selector)
与您尝试进行的查询无关,我很确定它会引发您的错误。您的查询完全错误。要获取数据,您应该使用聚合框架并执行以下操作:
- 选择具有所需
userid
的文件 - 展开历史数组
- 查找所需的历史条目
MongoDB 查询的简短版本(如果您只想获取历史条目,它不包括
$projec
步骤)是(自己将其转换为 Go):db.history.aggregate( {$match: { userid: ObjectId("58808d735ba19c2797f486c9") }}, {$unwind: "$history"}, {$match: { "history.time": {"$gte":ISODate("2017-01-17T09:57:34.574Z"), "$lte":ISODate("2017-01-20T09:57:34.574Z")} }} )
如果
history
数组在您编写时“非常大”,此操作将非常慢。我不知道如果最大 BSON 大小为 16Mb,这个数组怎么会“非常大”,但是没关系(我希望你在决定将用户的历史记录存储在嵌套数组中时阅读有关文档大小限制的文档)。没有看起来那么简单?帮自己一个忙 - 只需使用 RDBMS 并在单个查询中将此数据检索到具有索引
time
和user_id
字段的history
表。- 选择具有所需
关于mongodb - 在嵌入式数组 golang 中检索范围时间 mongodb 之间的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41749657/