Как определить оболочку типа для ObjectID примитива?

Я использую MongoDB для разработки системы продажи билетов с использованием Go. У меня есть две сущности: пользователи и билеты, каждая из которых имеет свой уникальный идентификатор. Я хотел бы иметь возможность различать два типа идентификаторов, чтобы функции могли запрашивать получение либо UserID, либо TicketID.

Я попытался определить два новых типа, базовым типом которых является primitive.ObjectID:

type UserID primitive.ObjectID
type TicketID primitive.ObjectID

Затем я использовал этот тип в своей пользовательской структуре:

type User struct {
  ID UserID `json:"id" bson:"_id"`
}

Наконец, я попытался получить массив всех пользователей в базе данных, используя этот код:

func (coll *mongo.Collection) GetAllUsers(ctx context.Context) ([]User, error) {
  cursor, err := coll.Find(ctx, bson.D{})
  if err != nil {
    return []User{}, err
  }
  users := []User{}
  err = cursor.All(ctx, &users)
  if err != nil {
    return []User{}, err
  }
  return users, nil
}

Однако попытка сделать это приводит к следующей ошибке: cannot decode ObjectID into an array

Как я могу добиться различия между UserID и TicketID, избежав при этом этой ошибки?

Структура пользователя и теги выглядят правильно. Как вы расшифровываете результат? Это должно выглядеть примерно так: go func GetUserByID(ctx context.Context, id UserID) (*User, error) { var user User coll := mongoClient.Database("my-db").Collection("my-collection") result := coll.FindOne(ctx, bson.M{"_id": id}) if err := result.Decode(&user); err != nil { return &user, err } return &user, nil }

EricFrancis12 21.08.2024 23:55

Для декодирования результатов я использую следующую функцию: func (coll *mongo.Collection) GetAllUsers(ctx context.Context) ([]User, error) { cursor, err := coll.Find(ctx, bson.D{}) if err != nil { return []User{}, err } users := []User{} err = cursor.All(ctx, &users) if err != nil { return []User{}, err } return users, nil }

Louis 22.08.2024 01:26

@Louis Поместите код и информацию в свой комментарий выше в свой вопрос.

aneroid 22.08.2024 04:06
Использование JavaScript и MongoDB
Использование JavaScript и MongoDB
Сегодня я собираюсь вкратце рассказать о прототипах в JavaScript, а также представить и объяснить вам работу с базой данных MongoDB.
2
3
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Определение типа создает новый, отдельный тип и удаляет его методы:

type UserID primitive.ObjectID

type TicketID primitive.ObjectID

После этого пакеты mongo и bson больше не будут распознавать UserID и TicketID как ObjectID (так же, как их базовый массив байтов) и не будут знать, как демаршалировать в них MongoDB ObjectID.

Вместо этого используйте псевдонимы типов, тогда в вашем коде будут разные имена, а поскольку псевдоним типа не создает новый тип (просто привязывает другой идентификатор к тому же типу), он будет работать так, как вы ожидаете:

type UserID = primitive.ObjectID

type TicketID = primitive.ObjectID

Обратите внимание, что после приведенных выше объявлений типов UserID, TicketID и primitive.ObjectID будут одного и того же, идентичного типа, поэтому не стоит ожидать, что вы сможете различать их по типу.

Помешает ли это разработчику передать TicketID в функцию, ожидающую UserID?

Louis 22.08.2024 13:07

@ Луи Нет, это не так. Но MongoDB не хранит ваш тип Go, а хранит только тип ObjectId, который использует внутри. Так что на самом деле нет никакого смысла/инструмента для борьбы с этим.

icza 22.08.2024 13:32

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