Как установить все данные в срезе, полученные из mongodb с помощью mgo?

Я пытаюсь получить данные из MongoDB с динамическими ключами и установить их в срезе.

Вот мой образец данных:

_id ObjectIdHex("5911786dc28f25578150501d")
2017-05-01 [800 1000 1200 1400 1600]
_id ObjectIdHex("59117897c28f25578150501e")
2017-05-02 [800 1000 1200 1400 1600]
_id ObjectIdHex("5911789ec28f25578150501f")
2017-05-03 [800 1000 1200 1400 1600]
2017-05-04 [800 1000 1200 1400 1600]
_id ObjectIdHex("591178a6c28f255781505020")
_id ObjectIdHex("591178abc28f255781505021")
2017-05-05 [800 1000 1200 1400 1600]
_id ObjectIdHex("591178b0c28f255781505022")
2017-05-06 [800 1000 1200 1400 1600]
_id ObjectIdHex("591178b5c28f255781505023")
2017-05-07 [800 1000 1200 1400 1600]
_id ObjectIdHex("591178bac28f255781505024")
2017-05-08 [800 1000 1200 1400 1600]
_id ObjectIdHex("591178c8c28f255781505025")
2017-05-09 [800 1000 1200 1400 1600]
2017-05-10 [800 1000 1200 1400 1600]

Мне нужно установить его в массив, например {2017-05-09 : [800 1000 1200 1400 1600]}, и то же самое для других записей.

я пытался

package main

import(
    "fmt"
    "gopkg.in/mgo.v2/bson"
    //"encoding/json"
)

type Spot struct{
    Id      bson.ObjectId   `json:"_id,omitempty" bson:"_id,omitempty"`
    Spots   map[string]interface{} `json:"spots"`
}

//type Values []Value

//var result []struct{ Value int }
type Spots []Spot

func getAllSpots() (Spots) {
    mongoSession := getDbSession()

    sessionCopy := mongoSession.Copy()
    defer sessionCopy.Close()
    var spots []Spot
    c := mongoSession.DB("test").C("spots")
    var data []bson.M
    err := c.Find(bson.M{}).All(&data)
    if err != nil {
        panic(err)
        // TODO: Do something about the error
    }

    test := make(map[string]int)
    for _, doc := range data {
      for key, value := range doc {
        if(key == "_id"){
            test[key] = value
            fmt.Println(key, value)
        }
      }
    }    

    return spots
}

Я могу получить пятна в данных и могу записать вывод в консоль, используя fmt.Println(), но когда я назначаю его срезу, это дает мне следующую ошибку:

нельзя использовать значение (тип интерфейса {}) как тип int в назначении: требуется утверждение типа

Я искал по всему Интернету, но не смог найти действительного решения. Может ли кто-нибудь помочь мне, что я делаю неправильно?


person MKB    schedule 11.05.2017    source источник
comment
В какой строке сообщается об этой ошибке?   -  person Adrian    schedule 11.05.2017


Ответы (1)


Если вы посмотрите документацию для bson.M, вы увидите, что это просто псевдоним для map[string]interface{}. Это означает, что когда вы range над ним, ваш ключ будет string, а ваше значение будет interface{}. Ваша цель — map[string]int. Итак, когда вы test[key] = value, вы пытаетесь присвоить value (interface{}) чему-то, ожидающему int, что вы не можете сделать без явного приведения (также известного как утверждение типа). Это именно то, что говорит сообщение об ошибке: cannot use value (type interface {}) as type int in assignment: need type assertion. Вместо этого вы могли бы сделать:

test[key] = value.(int)

Но, как заметил путу, похоже, что эти значения на самом деле представляют собой массивы int, что вообще не соответствует типу test, поскольку это сопоставление строк с отдельными значениями int. Поэтому вам нужно либо изменить тип test на map[string][]int, либо выбрать значение из исходного массива для сохранения на карте, например.

test[key] = (value.([]int))[0]
person Adrian    schedule 11.05.2017
comment
Поскольку данные представляют собой массив чисел, я думаю, что это должно быть value.([]int) или, может быть, value.([]float64). Не так ли? - person putu; 11.05.2017
comment
Привет @Adrian Спасибо, ребята, за ответ. Я бы проверил это в ближайшее время, но поскольку я был занят какой-то другой высокоприоритетной работой, поэтому не могу проверить это прямо сейчас. Спасибо! - person MKB; 13.05.2017