英文:
Retrieve from database via mgo using interface
问题
我有以下(未经测试的)函数:
func Execute(task MyInterface) {
db := session.DB(task.Database()).C(task.Collection())
var tasks []MyInterface
db.Find(nil).All(&tasks)
for _, t := range tasks { t.Do() }
}
我想给我的函数一个实现了接口MyInterface
的结构体。然后它应该从mongodb中检索一些值,并调用检索到的结构体上的一个方法。
问题是错误:reflect.Set:类型为bson.M的值无法分配给类型mypkg.MyInterface
- 有没有办法让它工作?我尝试使用原始结构体的类型来实例化tasks
,但无法使其工作。
任何帮助将不胜感激 - 谢谢
英文:
I have following (untested) function:
func Execute(task MyInterface) {
db := session.DB(task.Database()).C(task.Collection())
var tasks []MyInterface
db.Find(nil).All(&tasks)
for _, t := range tasks { t.Do() }
}
I want to give my function a struct that implements interface MyInterface
. It should then retrieve some values from mongodb and call a method on the retrieved structs.
Problem is error: reflect.Set: value of type bson.M is not assignable to type mypkg.MyInterface
- is there some way to make this work? I tried to instantiate tasks
using the type of the original struct, but couldn't get it working.
Any help would be appreciated - thanks
答案1
得分: 1
mgo
无法创建MyInterface
对象,因为MyInterface
只是一个接口。尝试这样做:
myObject := &MyInterface{} //失败
我认为这基本上是mgo
尝试为每个要解组的记录所做的操作。
要实现你想要的效果,将tasks
定义为[]map[string]interface{}
或[]bson.M
类型,然后:
for _, o := range tasks {
t := &MyTypeThatImplementsMyInterface{
Field1 : o["my_field"],
//等等
}
t.Do()
}
要么将tasks
定义为一个实现MyInterface
的类型的切片(var tasks []MyStructType
),并且其字段与数据库中的bson对象的键和值类型匹配。如果存储的数据是多个实现MyInterface
的类型,则可能无法正常工作,因此上面的切片和映射选项要小心。
此外,对于Find(nil).All(&tasks)
要小心。如果该集合中有数百万条记录,并且记录的大小较大,可能会导致内存不足。
英文:
mgo
can't create MyInterface
objects since MyInterface is just an interface. Try doing :
myObject := &MyInterface{} //fails
I think it's basically what mgo
is trying to do for each record it tries to unmarshal.
To achieve what you want, make tasks
of type []map[string]interface{}
or []bson.M
(the latter is an alias for the former) and then:
for _, o := range tasks {
t := &MyTypeThatImplementsMyInterface{
Field1 : o["my_field"],
//etc.
}
t.Do()
}
Either that or make tasks
a slice of objects of a type (var tasks []MyStructType
) that implements MyInterface
and that its fields match the keys and values types of your bson objects in your database. That might not work if your stored data is of more than one type implementing MyInterface
, hence the slice of maps option above.
Also, be cautious with Find(nil).All(&tasks)
. If you have millions of records in that collection, depending on the records size, you may fall short of memory.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论