map [string] interface {} не обрабатывается правильно после переключения на новый драйвер go mongo - PullRequest
0 голосов
/ 26 апреля 2019

Я переключаюсь на новый драйвер mongo go (mongo-go-driver), в отличие от mgo

Одна из наших функций больше не работает, несмотря на то, что метод декодирования не меняется (в карту [строка] interface {})

Я полагаю, что происходит то, что возвращаемые данные не обрабатываются как карта [string] interface {}

Полученные данные являются агрегированным запросом Монго:

result = map[query_key:procedure_on_cities query_type:run procedure query_value:map[aggregate:[map[£match:map[Source:Cities]] map[£sort:map[Order:1]]] collection:aggregate_stats db:stats] _id:ObjectID("5c5410fac2a7b1b1beae52bc")]

Что нам нужно сделать, это заменить символ £ на $ в агрегации, чтобы он работал правильно (изначально мы кодируем $ как £, чтобы не столкнуться с проблемами с $неправильно интерпретируется, когда запрос составляется на внешнем интерфейсе

Ранее с помощью mgo мы просто делали это:

if returnedQuery, ok := result["query_value"].(map[string]interface{}); ok {
        queryToRun = replace£With$(returnedQuery)
}

Но это больше не работает ...

Итак, бит, который мы хотим обработать как интерфейс map [string] для передачи в функцию, таков:

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

Мы предположили, что, как и в случае с mgo, мы могли бы просто сделать ранее упомянутое утверждение типа

В моем тестеg, я изолирую часть с символом £, который я хочу заменить:

result2 = result["query_value"].(map[string]interface{})

Затем я хочу проверить, чтобы увидеть типы данных и является ли то, что находится в совокупности, интерфейсом map [string] {}

    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("Please, print this", keyMSI)
        }
    }

Но это не печатает последнее утверждение.ЗАЧЕМ?!Вот каков результат2:

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

Это интерфейс [] {}, не так ли ?!Он должен печатать этот оператор, так как значение агрегированного ключа является массивом, содержащим карты

При выполнении проверок типа ответ был:

primitive.A 

Примитив. Не обработан.как [] интерфейс {}?

1 Ответ

0 голосов
/ 29 апреля 2019

Проблема здесь в том, что новый драйвер Монго использует примитив. Тип данных для интерфейса [] {}

* примитив. А имеет базовый тип данных интерфейса [] {} , нолитерал типа является примитивным. A

Чтобы решить эту проблему, сначала необходимо выполнить утверждение типа для примитива. А затем выполнить преобразование в тип литерала [] interface {}:

I 'мы импортировали пакет для примитива bson с именем:

import (
    bsonNewGoDriverPrimitive "go.mongodb.org/mongo-driver/bson/primitive"
)

if valuePA, ok := value.(bsonNewGoDriverPrimitive.A); ok {
        vI := []interface{}(valuePA)}
...