Как десериализовать вывод из mongo-go-driver в виде массива bson в интерфейс [] {}, когда primitive.A - интерфейс bson [] - PullRequest
1 голос
/ 26 апреля 2019

У меня есть интерфейс map [string] {}, сгенерированный по запросу mongo, использующему новый драйвер mongo-go

Я хочу обработать определенные значения на карте и заменить символы £ взначения, принадлежащие агрегированному ключу

Вот карта:

result2 = map[aggregate:[map[£match:map[Source:Cities]] map[£sort:map[Order:1]]] collection:aggregate_stats db:stats]

Цикл по карте:

    for key, value := range result2 {
        fmt.Println("key from result2:", key, " || ", "value from result 2:", value)
        if key == "aggregate" {
            fmt.Println("FOUND AGGREGATE || ", "value:", value, " || type: ", reflect.TypeOf(value))
        }
        if valueMSI, ok := value.([]interface{}); ok {
            fmt.Println("Working", valueMSI)
            fmt.Println(reflect.TypeOf(valueMSI))
        }
    }

Теперь в операторе if выполняется проверка дляключ агрегации, вывод первого оператора печати дает тип как:

primitive.A

Но это выглядит как [] интерфейс {} карт при печати?[см. результат2]

Учитывая это, почему не вычисляется второй оператор if?

Означает ли это, что primitive.A! = массив интерфейсов?

В документации https://godoc.org/go.mongodb.org/mongo-driver/bson/primitive тип A определяется как «A представляет массив BSON. Этот тип может использоваться для представления массива BSON в краткой и удобочитаемой форме. Обычно его следует использоватьпри сериализации в BSON. Для десериализации следует использовать типы RawArray или Array. "

Как я могу это сделать?Я хочу получить доступ к значениям для совокупного ключа?

1 Ответ

2 голосов
/ 26 апреля 2019

Вы можете преобразовать значение типа primitive.A в []interface{}, используя выражение преобразования , форма которого T(x).

Так что в вашем случае вы можете сделать это:

for key, value := range result2 {
    fmt.Println("key from result2:", key, " || ", "value from result 2:", value)
    if key == "aggregate" {
        fmt.Println("FOUND AGGREGATE || ", "value:", value, " || type: ", reflect.TypeOf(value))
    }
    if pa, ok := value.(primitive.A); ok {
        valueMSI := []interface{}(pa)
        fmt.Println("Working", valueMSI)
        fmt.Println(reflect.TypeOf(valueMSI))
    }
}

Как объяснено в документации, вы можете преобразовать непостоянное значение x в тип T в любом из этих случаев (я добавил длярегистр, соответствующий вашему вопросу):

  • x можно присвоить T.
  • игнорируя теги struct (см. ниже), тип x и T имеют идентичные базовые значениятипы.
  • игнорируя теги struct (см. ниже), тип x и T являются типами указателей, которые не являются определенными типами, и их базовые типы указателей имеют идентичные базовые типы.
  • тип xи T оба являются целочисленными или с плавающей запятой.
  • тип x и T оба являются сложными типами.
  • x является целым числом или фрагментом байтов или рун, а T является строковым типом.
  • x - строка, а T - фрагмент байтов или рун.

Немного о базовых типах (выделение добавлено):

Каждый тип T имеет базовый тип : если T является одним из предварительно объявленных логических, числовыхили строковые типы, или литерал типа , соответствующий базовый тип - это сам T.В противном случае базовый тип T является базовым типом типа, на который ссылается T в своем объявлении типа.

Поскольку primitive.A определяется с использованием литерала типа []interface{} имеет тот же базовый тип , что и []interface{}.

  • Базовый тип []interface{} равен []interface{}.
  • .базовый тип primitive.A равен []interface{}.
...