doutan4831 2015-02-27 23:11
浏览 103
已采纳

将mgo与转换为map [string] interface {}的嵌套文档一起使用。 如何遍历地图?

I have the following documents in a MongoDB database, but sometimes I don't know the structure for certain:

{
    "_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.)"
        }
    ]
}

I have used the following code to query the database and am attempting to build an array of just the "date" and "temp" from forecast sub-document and have so far used the following code, but can't get to the point where I can query on the key to get the value:

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)
    }
}

The output I'm getting is:

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.)]

I am fairly new to go and unsure of how to extract the value from date and temp. Any help would be greatly appreciated.

  • 写回答

1条回答 默认 最新

  • doujuyang1764 2015-03-11 00:10
    关注

    After much research and forum searching I found an answer to the aforementioned problem.

    Since I knew some basic information about my structure, I knew there was a timestamp and that there was going to a sub-document related to the forecast key:

    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))
    }
    

    Basically I used map[string]interface to solve the problem of my unknown forecast sub-document structure. From that I was then able to loop through and extract the necessary information.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)