检索嵌入数组golang中的范围时间mongodb之间的值

时间:2017-01-19 19:01:01

标签: mongodb go time range

这是我的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)
    }

我收到了一个错误:

  

无法规范化查询:BadValue不支持的投影选项:历史记录:{time:{$ gte:new Date(1484819854576),$ lte:new Date(1484819854576)}}

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

  1. 您可以在编写代码之前阅读文档。

      

    func(q *查询)选择(选择器界面{})*查询

         

    选择允许选择应为找到的结果检索哪些字段。例如,以下查询仅检索名称字段:

         

    err := collection.Find(nil).Select(bson.M{"name": 1}).One(&result)

         

    相关文件:

         

    https://docs.mongodb.com/v3.2/tutorial/project-fields-from-query-results/#return-the-specified-fields-and-the-id-field-only(链接更改为实际的链接)

    Source

    因此,您的Select(selector)与您尝试进行的查询无关,我很确定它会引发您的错误。

  2. 您的查询完全错误。要获取数据,您应该使用聚合框架并执行下一步:

    1. 选择所需文件userid
    2. 展开历史数组
    3. 查找所需的历史记录条目
    4. 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数组“非常大”,那么这个操作会很慢。我不知道如果max BSON大小是16Mb,这个数组怎么会“非常大”,但是好的(我希望你在决定在嵌套数组中存储用户的历史时阅读有关文档大小限制的文档)。

      看起来不那么容易?帮自己一个忙 - 只需使用RDBMS并在单个查询中将此数据检索到带有索引historytime字段的user_id表。