Вставка данных в MongoDB с помощью mgo

Я пытаюсь вставить некоторые данные в MongoDB с помощью Go.

Вот структура данных:

type Entry struct {
    Id          string `json:"id",bson:"_id,omitempty"`
    ResourceId  int    `json:"resource_id,bson:"resource_id"`
    Word        string `json:"word",bson:"word"`
    Meaning     string `json:"meaning",bson:"meaning"`
    Example     string `json:"example",bson:"example"`
}

Это моя функция вставки:

func insertEntry(db *mgo.Session, entry *Entry) error {
    c := db.DB(*mongoDB).C("entries")
    count, err := c.Find(bson.M{"resourceid": entry.ResourceId}).Limit(1).Count()
    if err != nil {
        return err
    }
    if count > 0 {
        return fmt.Errorf("resource %s already exists", entry.ResourceId)
    }
    return c.Insert(entry)
}

И, наконец, вот как я это называю:

entry := &Entry{
    ResourceId:  resourceId,
    Word:        word,
    Meaning:     meaning,
    Example:     example,
}
err = insertEntry(db, entry)
if err != nil {
    log.Println("Could not save the entry to MongoDB:", err)
}

Проблема в том, что я ожидал, что мои теги bson сработают волшебным образом, но они не работают. Вместо сохранения данных как:

{ "_id": ObjectId ("53700d9cd83e146623e6bfb4"), "resource_id": 7660708, "word": "Foo" ...}

Он сохраняется как:

{ "_id" : ObjectId("53700d9cd83e146623e6bfb4"), "id" : "", "resourceid" : 7660708, "word" : "Foo"...}

Как я могу это исправить?


person if __name__ is None    schedule 11.05.2014    source источник


Ответы (3)


Изменить запись на:

type Entry struct {
    Id          string `json:"id" bson:"_id,omitempty"`
    ResourceId  int    `json:"resource_id" bson:"resource_id"`
    Word        string `json:"word" bson:"word"`
    Meaning     string `json:"meaning" bson:"meaning"`
    Example     string `json:"example" bson:"example"`
}

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

person TrevorSStone    schedule 12.05.2014
comment
это не верно. не только Id должен иметь тип bson.ObjectId, но и теги bson не нужны, за исключением ResourceId, который не преобразуется автоматически в resource_id. Поля структуры в верхнем регистре преобразуются в нижний регистр с помощью mgo. Требуется только имя поля json в нижнем регистре. - person ; 12.05.2014
comment
@dalu На самом деле _id может быть любого типа. Редактировать: Ну, если только ОП не ожидал ObjectId, что не совсем ясно из вопроса. - person Gustavo Niemeyer; 12.05.2014
comment
@dalu, как сказал Густаво, _id не обязательно должен быть ObjectId. Это значение по умолчанию, но не всегда необходимый выбор. Кроме того, нет ничего плохого. Лично я считаю, что использование тега структуры bson в долгосрочной перспективе является лучшей практикой, даже если это одно и то же. Представьте, если появится будущий разработчик и решит изменить переменную Word на Title. Без определения тега bson они будут изменять хранилище данных, не осознавая этого. Сохранение тега bson помогает в обслуживании в будущем, IMO, и, что еще хуже, заставляет вас вводить еще несколько символов для ясности. - person TrevorSStone; 13.05.2014

type Entry struct {
    Id          bson.ObjectId `bson:"_id,omitempty" json:"id"`
    ResourceId  int           `json:"resource_id" bson:"resource_id"`
    Word        string        `json:"word"`
    Meaning     string        `json:"meaning"`
    Example     string        `json:"example"`
}

Вместо Count() и Insert() вы можете использовать UpsertId, который делает именно это, если идентификатор существует, запись заменяется, если она не вставлена.

Insert() с пустым ObjectId позволяет MongoDB обрабатывать присвоение идентификатора.

Изменить: неправильно прочитать ваш запрос Count. У вас тоже ошибка. Это должно быть «resource_id», а не «resourceid», потому что вы объявили, что поле bson называется «resource_id».

person Community    schedule 12.05.2014
comment
То, как работает insertEntry, может показаться нелогичным, но оно имеет смысл в том, как работает программа. - person if __name__ is None; 12.05.2014
comment
да, поправил. Я думал, вы проверяете, существует ли objectId, а затем вставляете новую запись. - person ; 12.05.2014
comment
втф это правильный ответ. Идентификатор должен быть bson.ObjectId - person ; 12.05.2014
comment
Если мы не вставим идентификатор объекта, монго создаст параметр _id по умолчанию. - person Himanshu; 03.01.2018

Обновите свою структуру Entry как:

type Entry struct {
    Id          string `bson:"_id"`
    ResourceId  int    `json:"resource_id,omitempty"`
    Word        string `json:"word,omitempty"`
    Meaning     string `json:"meaning,omitempty"`
    Example     string `json:"example,omitempty"`
}

Это должно работать!

person Jyotsna Gupta    schedule 11.05.2019