将mgo与转换为map[string]接口{}的嵌套文档一起使用.如何迭代地图



我在MongoDB数据库中有以下文档,但有时我不确定其结构:

{
    "_id" : ObjectId("54e58ea6128ae6385faa576e"),
    "date" : ISODate("2015-02-19T00:00:00.000Z"),
    "lat" : "53.5558774",
    "lng" : "-113.4939486",
    "apparentTemp" : -1.727777777777777,
    "timezone" : "America/Edmonton",
    "humidity" : 0.92,
    "city" : "Edmonton",
    "dewPoint" : 26.85,
    "temp" : -1.727777777777777,
    "summary" : "Light Snow",
    "gmt_offset" : -7,
    "windSpeed" : 0.13,
    "windBearing" : 87,
    "precipIntensity" : 0.0086,
    "precipProbability" : 0.44,
    "forecast" : [ 
        {
            "humidity" : 0.86,
            "windSpeed" : 0.86,
            "precipProbability" : 0.83,
            "dewPoint" : 28.26,
            "temp" : -0.02777777777777817,
            "date" : ISODate("2015-02-19T00:00:00.000Z"),
            "windBearing" : 63,
            "precipIntensity" : 0.0528,
            "apparentTemp" : -0.02777777777777817,
            "summary" : "Snow (Under 1 in.)"
        }
    ]
}

我已经使用以下代码来查询数据库,并试图从预测子文档中构建一个仅包含"日期"one_answers"临时"的数组,到目前为止,我已经使用了以下代码,但无法查询关键字以获得值:

var results bson.M
err2 := collection.Find(bson.M{
    "city": vars["city"],
    "forecast.1": bson.M{"$exists": true},
}).Sort("-date").One(&results)
if err2 != nil {
    log.Fatal(err2)
}
switch reflect.TypeOf(results["forecast"]).Kind() {
case reflect.Slice:
    s := reflect.ValueOf(results["forecast"])
    for i := 0; i < s.Len(); i++ {
        hourly_temps := s.Index(i).Interface()
        fmt.Fprintln(w, hourly_temps)
    }
}

我得到的输出是:

map[humidity:0.86 temp:-.0277777777777817 windBearing:63 windSpeed:0.86        precipProbability:0.83 dewPoint:28.26 date:2015-02-19 00:00:00 -0700 MST precipIntensity:0.0528 apparentTemp:-0.02777777777777817 summary:Snow (Under 1 in.)]

我是一个新手,不知道如何从日期和临时中提取价值。如果有任何帮助,我将不胜感激。

经过大量的研究和论坛搜索,我找到了上述问题的答案。

由于我知道关于我的结构的一些基本信息,我知道有一个时间戳,并且有一个与预测密钥相关的子文档:

package main
import (
    "fmt"
    "github.com/gorilla/mux"
    "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
    "log"
    "net/http"
    "time"
)
var (
    mgoSession *mgo.Session
)
func ConnectDb() {
    if mgoSession == nil {
        session, err := mgo.Dial("localhost")
        if err != nil {
            log.Print(err)
        }
        session.SetMode(mgo.Monotonic, true)
        mgoSession = session
    }
    return
}
func CloseDb() {
    mgoSession.Close()
    return
}
type WeatherForecastData struct {
    Timestamp time.Time                `json:"timestamp,omitempty" bson:"date,omitempty"`
    Forecast  []map[string]interface{} `json:"forecast" bson:"forecast"`
}
type WeatherFutureForecast struct {
    Timestamp   time.Time `json:"timestamp,omitempty" bson:"date,omitempty"`
    Temperature float64   `json:"temperature"`
}
func GetWeatherForecast(city string) []WeatherFutureForecast {
    session := mgoSession.Clone()
    defer session.Close()
    collection := mgoSession.DB("db").C("weather_forecast_io")
    var results WeatherForecastData
    var forecastResults []WeatherFutureForecast
    err := collection.Find(bson.M{
        "city":       city,
        "forecast.1": bson.M{"$exists": true},
    }).Sort("-date").One(&results)
    if err != nil {
        log.Print(err)
    } else {
        for _, value := range results.Forecast {
            if _, ok := value["date"]; ok {
                if _, ok2 := value["temp"]; ok2 {
                    date := value["date"].(time.Time)
                    temp := value["temp"].(float64)
                    day := WeatherFutureForecast{Timestamp: date, Temperature: temp}
                    forecastResults = append(forecastResults, day)
                }
            }
        }
    }
    return forecastResults
}
func main() {
    ConnectDb()
    defer CloseDb()
    router := mux.NewRouter().StrictSlash(true)
    router.HandleFunc("/weather/forecast/{city}", WeatherForecast)
    log.Fatal(http.ListenAndServe(":8080", router))
}

基本上,我使用map[string]接口来解决我未知的预测子文档结构的问题。然后,我能够循环浏览并提取必要的信息。

最新更新