Как определить оболочку типа для 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, избежав при этом этой ошибки?

🤔 А знаете ли вы, что...
MongoDB позволяет создавать географические индексы и выполнять запросы на основе местоположения...


2
50
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 будут одного и того же, идентичного типа, поэтому не стоит ожидать, что вы сможете различать их по типу.