GoLang Unmarshal JSON из результатов эластичного поиска

У меня есть данные, полученные от Elasticsearch с использованием github.com/olivere/elastic. Такие работы, когда я добавляю его в свою структуру и натягиваю ее, например,

data := Api {
    Total: myTotal,
    Data: string(result),
}

c.JSON(http.StatusOK, totalData)

api - это такая структура,

type Api struct {
   Total interface{}
   Data interface{} 
}

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

"Data":"{\"CID\":\"XXXXXXXXXX\",\"Link\":\"XXXXXXXXX\",

Поэтому я попытался демаршалировать данные перед добавлением их в структуру api.

var p DataApi

err := json.Unmarshal(result, &p)
if err != nil {
    panic(err)
}

totalData := Api {
    Total: myTotal,
    Data: p,
}

c.JSON(http.StatusOK, totalData)

Этот вид работает нормально, возвращает данные правильным образом, но только при загрузке одного результата. Когда запрашиваются 2 или более результатов, я получаю эту ошибку из-за паники без маршала.

invalid character '{' after top-level value

Я пробовал и гуглил повсюду, но не могу найти решение этой проблемы? Я не уверен, что делаю не так? DataApi - это вложенный набор структур, я не был уверен, есть ли что-то, что мне нужно из-за этого?

Это выполняется в рамках Gin.

Спасибо.

РЕДАКТИРОВАТЬ

Поэтому, когда я использую fmt.Println в строке (результат), я могу вывести на экран любое количество результатов. Как я могу добавить это в структуру API, а затем мне нужна структура, преобразованная в данные JSON. Есть ли способ добавить эти строковые данные в преобразованную структуру API JSON?


person Coder99    schedule 17.04.2018    source источник
comment
можете ли вы привести пример того, как string(result) выглядит с одним и несколькими результатами?   -  person Verran    schedule 18.04.2018
comment
Это то, что должно быть, {CID: XXXXXXXXXX, Link: XXXXXXXXX,} и т. Д.   -  person Coder99    schedule 18.04.2018


Ответы (3)


Попробуйте демаршалировать несколько результатов в срез:

var q []Api
err = json.Unmarshal(result, &q)

См. На игровой площадке https://play.golang.org/p/D_bVAd4jBlI

package main

import (
    "encoding/json"
    "fmt"
)

type Api struct {
    Total interface{}
    Data  interface{}
}

func main() {

    data := Api{
        Total: 1,
        Data:  "2",
    }

    result, err := json.Marshal(data)
    if err != nil {
        panic(err)
    }

    fmt.Printf("single data: %s\n", result)

    var p Api
    err = json.Unmarshal(result, &p)
    if err != nil {
        panic(err)
    }

    dataSlice := []Api{data}

    result, err = json.Marshal(dataSlice)
    if err != nil {
        panic(err)
    }

    fmt.Printf("slice of data: %s\n", result)

    var q []Api
    err = json.Unmarshal(result, &q)
    if err != nil {
        panic(err)
    }
}
person Everton    schedule 18.04.2018
comment
Просто попробовал это, и я получаю ту же ошибку, недопустимый символ '{' после значения верхнего уровня - person Coder99; 18.04.2018
comment
@ Coder99 Вы пытались запустить пример на игровой площадке play.golang.org/p/D_bVAd4jBlI? - person Everton; 18.04.2018
comment
Сделаю, извините, был занят весь день, сейчас разбираюсь более подробно. Спасибо - person Coder99; 18.04.2018
comment
Я новичок, но не вижу, как это мне поможет, я пробовал это с моими данными и все равно получаю ту же ошибку. Я обновил вопрос - person Coder99; 18.04.2018
comment
@ Coder99 Можете ли вы отредактировать пример на игровой площадке, чтобы предоставить работоспособный код, точно показывающий, как он у вас не работает? - person Everton; 18.04.2018

Используйте json.RawMessage для хранения произвольных документов JSON:

var p json.RawMessage

err := json.Unmarshal(result, &p)
if err != nil {
    panic(err)
}

totalData := Api {
    Total: myTotal,
    Data: p,
}

c.JSON(http.StatusOK, totalData)
person Peter    schedule 18.04.2018
comment
Просто дайте это назад и все равно получите ту же ошибку, недопустимый символ '{' после значения верхнего уровня - person Coder99; 18.04.2018
comment
Это говорит о том, что вы пытаетесь демаршалировать несколько объединенных документов JSON. Вместо этого используйте json.Decoder: play.golang.org/p/85WPi0NxYrT - person Peter; 18.04.2018

У меня есть рабочее решение моей проблемы, я просто использую Hits Hits Из данных, возвращаемых эластичным поиском, мне нужны только исходные данные, но я думаю, что он делает то, что мне нужно ... пока.

Спасибо.

person Coder99    schedule 18.04.2018