如何使用mgo将从mongodb获取的切片中的所有数据进行设置?

huangapple go评论86阅读模式
英文:

How to set all data in a slice, got from mongodb using 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
}

我能够获取数据中的spots,并使用fmt.Println()将输出写入控制台,但是当我将其分配给切片时,它给出以下错误:

cannot use value (type interface {}) as type int in assignment: need type assertion

我在网上搜索了很多,但找不到有效的解决方案。有人能指导我做错了什么吗?

英文:

I am trying to fetch data from MongoDB that has dynamic keys and set it in a slice.

Here is my data sample:

_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]

I need to set it into an array like {2017-05-09 : [800 1000 1200 1400 1600]} and same for other entries.

I have tried

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
}

I am able to get the spots in data and able to write the output to the console using fmt.Println() but when I assign it to a slice it gives me the following error:

> cannot use value (type interface {}) as type int in assignment: need type assertion

I searched all over the web but couldn't find a valid solution. Can anyone please guide me what am I doing wrong?

答案1

得分: 1

如果你查看bson.M的文档,你会发现它只是map[string]interface{}的别名。这意味着当你对其进行range迭代时,你的键是一个string,值是一个interface{}。你的目标是一个map[string]int。所以当你执行test[key] = value时,你试图将value(一个interface{})赋给一个期望int类型的东西,而没有显式的类型转换(也称为type assertion)。这正是错误消息所说的:cannot use value (type interface {}) as type int in assignment: need type assertion。你可以这样做:

test[key] = value.(int)

但正如putu指出的那样,看起来这些值实际上是int数组,这与test的类型完全不匹配,因为它是一个将字符串映射到单个int值的映射。所以你需要将test的类型更改为map[string][]int,或者从源数组中选择一个值存储在映射中,例如:

test[key] = (value.([]int))[0]
英文:

If you look at the documentation for bson.M, you'll see that it's just an alias for map[string]interface{}. That means when you range over it, your key is a string, and your value is an interface{}. Your target is a map[string]int. So when you test[key] = value, you're trying to assign value (an interface{}) to something expecting an int, which you can't do without an explicit cast (aka type assertion). This is exactly what the error message says: cannot use value (type interface {}) as type int in assignment: need type assertion. You could instead do:

test[key] = value.(int)

But as a putu noted, it looks like those values are actually arrays of ints, which doesn't fit the test type at all, as it is a map of strings to single int values. So you'd need to either change the type of test to map[string][]int or pick a value from the source array to store in the map, e.g.

test[key] = (value.([]int))[0]

huangapple
  • 本文由 发表于 2017年5月11日 20:26:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/43915387.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定