2013-02-21 5 views
1

я следующее (непроверенных) функции:Получить из базы данных через интерфейс МдО с помощью

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 и вызвать метод для извлеченных структур.

Проблема error: reflect.Set: value of type bson.M is not assignable to type mypkg.MyInterface - есть ли способ сделать эту работу? Я попытался создать экземпляр tasks, используя тип исходной структуры, но не смог заставить его работать.

Любая помощь будет оценена - спасибо :)

+0

Когда вы говорите «Я попытался создать задачи, используя тип исходной структуры, но не смог заставить ее работать». Какова была ошибка и как вы это сделали? Были ли задания типа [] MyInterface [] MyStructType? – JimPaek

+0

@JimPaek: Sry, это было плохо написано: я просто попытался выяснить, как создать экземпляр типа оригинала. И не нашел пути. (То, что я хотел, было 'MyStructType'). –

ответ

1

mgo не может создавать MyInterface объекты, так как MyInterface только интерфейс. Попробуйте сделать:

myObject := &MyInterface{} //fails 

Я думаю, что это в основном то, что mgo пытается сделать для каждой записи он пытается распаковать.

Чтобы достичь того, чего вы хотите, сделать tasks типа []map[string]interface{} или []bson.M (последний является псевдонимом для первого), а затем:

for _, o := range tasks { 
    t := &MyTypeThatImplementsMyInterface{ 
     Field1 : o["my_field"], 
     //etc. 
    } 
    t.Do() 
} 

Либо это, либо сделать tasks ломтиком объектов типа (var tasks []MyStructType), который реализует MyInterface и что его поля соответствуют типам ключей и значений ваших объектов bson в вашей базе данных. Это может не сработать, если ваши сохраненные данные имеют более одного типа, реализующие MyInterface, следовательно, этот вариант фрагмента карт выше.

Также будьте осторожны с Find(nil).All(&tasks). Если у вас есть миллионы записей в этой коллекции, в зависимости от размера записей, вы можете потерять память.

+0

Я вижу. Да, существует много неизвестных типов, которые реализуют этот интерфейс (я имею в виду, вот для каких интерфейсов для ...). Означает ли это, что есть решение моей проблемы? Или я могу каким-то образом динамически создавать структуры MyTypeThatImplementsMyInterface? –

+0

Рассмотрите возможность использования итератора http://godoc.org/labix.org/v2/mgo#Iter. Вы можете получить каждую запись в объекте bson.M, затем проверить наличие полей и затем создать из них конкретный объект. – JimPaek