Анонимные структуры возвращают пустое значение поля

type (

    Id struct {
        // I previously forgot to add the `ID` field in my question, it is present in my code but not on this question as @icza pointed it out to me
        ID bson.ObjectId `json:"id" bson:"_id"`
    }

    User struct {
        // When using anonymous struct, upon returning the collection, each of the document will have an empty `id` field, `id: ""`
        Id
        Email string `json:"email" bson:"email"`
        ...
    }

    // This works
    User2 struct {
        ID bson.ObjectId `json:"id" bson:"_id"`
        Email string `json:"email" bson:"email"`
    }
)

Возможно, я еще не полностью понял концепцию анонимных структур. В приведенном выше примере при запросе всех пользователей из коллекции id поле будет пустой строкой "", Однако, если я определю поле идентификатора напрямую в User структура, id показывает нормально. Разве это не то, для чего нужны анонимные структуры? В основном расширение структуры, чтобы вам не приходилось вводить их снова и снова?

Еще пример:

type SoftDelete struct {
    CreatedAt time.Time `json:"created_at" bson:"created_at"`
    UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
    DeletedAt time.Time `json:"deleted_at" bson:"deleted_at"`
}

type UserModel struct {
    SoftDelete
}

type BlogPost struct {
    SoftDelete
}

1 ответ

Решение

Проблема здесь в том, что поля, имеющие struct типы (включая встроенные структуры) отображаются как внедренные документы в MongoDB. Если вы не хотите этого, вы должны указать "inline" Флаг bson при встраивании структуры:

User struct {
    Id           `bson:",inline"`
    Email string `json:"email" bson:"email"`
}

Что за "inline" tag делает в MongoDB "выравнивает" поля встроенной структуры, как если бы они были частью структуры embedder.

Так же:

type UserModel struct {
    SoftDelete `bson:",inline"`
}

type BlogPost struct {
    SoftDelete `bson:",inline"`
}

Изменить: следующий раздел относится к оригиналу Id тип, который встроен bson.ObjectId , Позже спрашивающий пояснил, что это просто опечатка (и с тех пор редактировал вопрос), и это именованное неанонимное поле. Все еще думаю, что информация ниже полезна.

Одна вещь, чтобы отметить о вашем Id тип: ваш Id тип также встраивает bson.ObjectId:

Id struct {
    bson.ObjectId `json:"id" bson:"_id"`
}

Id не только имеет поле bson.ObjectId, но это встраивает это. Это важно, потому что таким образом вы Id Тип будет иметь String() метод повышен с bson.ObjectId и так будет User который встраивает Id, Сказав это, будет трудно пытаться напечатать или отладить значения типа User потому что вы всегда будете видеть его напечатанным как один ObjectId,

Вместо этого вы можете сделать это обычным полем в Id, встраивание Id в User все равно будет работать как положено:

Id struct {
    ID bson.ObjectId `json:"id" bson:"_id"`
}

См. Связанный вопрос + asnwer: принудительное сопоставление типов с помощью mgo

Другие вопросы по тегам