|
1 | 1 | package quickwit
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "bytes" |
4 | 5 | "encoding/json"
|
5 | 6 | "errors"
|
6 | 7 | "fmt"
|
@@ -49,14 +50,20 @@ func parseResponse(rawResponses []*json.RawMessage, targets []*Query, configured
|
49 | 50 | }
|
50 | 51 |
|
51 | 52 | for i, rawRes := range rawResponses {
|
| 53 | + target := targets[i] |
| 54 | + |
| 55 | + byteReader := bytes.NewReader(*rawRes) |
| 56 | + dec := json.NewDecoder(byteReader) |
| 57 | + if isLogsQuery(target) { |
| 58 | + dec.UseNumber() |
| 59 | + } |
52 | 60 | var res *es.SearchResponse
|
53 |
| - err := json.Unmarshal([]byte(*rawRes), &res) |
| 61 | + err := dec.Decode(&res) |
54 | 62 | if nil != err {
|
55 |
| - qwlog.Debug("Failed to unmarshal response", "err", err.Error(), "byteRes", *rawRes) |
| 63 | + qwlog.Debug("Failed to decode response", "err", err.Error(), "byteRes", *rawRes) |
56 | 64 | continue
|
57 | 65 | }
|
58 | 66 |
|
59 |
| - target := targets[i] |
60 | 67 | if res.Error != nil {
|
61 | 68 | errResult := getErrorFromElasticResponse(res)
|
62 | 69 | result.Responses[target.RefID] = backend.DataResponse{
|
@@ -269,14 +276,28 @@ func processDocsToDataFrameFields(docs []map[string]interface{}, propNames []str
|
269 | 276 | switch propNameValue.(type) {
|
270 | 277 | // We are checking for default data types values (float64, int, bool, string)
|
271 | 278 | // and default to json.RawMessage if we cannot find any of them
|
| 279 | + case json.Number: |
| 280 | + rawPropSlice := getDocPropSlice[json.Number](docs, propName, size) |
| 281 | + propSlice := make([]*float64, size) |
| 282 | + for i, val := range rawPropSlice { |
| 283 | + val_f64, err := val.Float64() |
| 284 | + if err == nil { |
| 285 | + propSlice[i] = &val_f64 |
| 286 | + } |
| 287 | + } |
| 288 | + allFields[propNameIdx] = createFieldOfType[float64](propSlice, propName, size, isFilterable) |
272 | 289 | case float64:
|
273 |
| - allFields[propNameIdx] = createFieldOfType[float64](docs, propName, size, isFilterable) |
| 290 | + propSlice := getDocPropSlice[float64](docs, propName, size) |
| 291 | + allFields[propNameIdx] = createFieldOfType[float64](propSlice, propName, size, isFilterable) |
274 | 292 | case int:
|
275 |
| - allFields[propNameIdx] = createFieldOfType[int](docs, propName, size, isFilterable) |
| 293 | + propSlice := getDocPropSlice[int](docs, propName, size) |
| 294 | + allFields[propNameIdx] = createFieldOfType[int](propSlice, propName, size, isFilterable) |
276 | 295 | case string:
|
277 |
| - allFields[propNameIdx] = createFieldOfType[string](docs, propName, size, isFilterable) |
| 296 | + propSlice := getDocPropSlice[string](docs, propName, size) |
| 297 | + allFields[propNameIdx] = createFieldOfType[string](propSlice, propName, size, isFilterable) |
278 | 298 | case bool:
|
279 |
| - allFields[propNameIdx] = createFieldOfType[bool](docs, propName, size, isFilterable) |
| 299 | + propSlice := getDocPropSlice[bool](docs, propName, size) |
| 300 | + allFields[propNameIdx] = createFieldOfType[bool](propSlice, propName, size, isFilterable) |
280 | 301 | default:
|
281 | 302 | fieldVector := make([]*json.RawMessage, size)
|
282 | 303 | for i, doc := range docs {
|
@@ -1076,15 +1097,21 @@ func findTheFirstNonNilDocValueForPropName(docs []map[string]interface{}, propNa
|
1076 | 1097 | return docs[0][propName]
|
1077 | 1098 | }
|
1078 | 1099 |
|
1079 |
| -func createFieldOfType[T int | float64 | bool | string](docs []map[string]interface{}, propName string, size int, isFilterable bool) *data.Field { |
1080 |
| - fieldVector := make([]*T, size) |
| 1100 | +func getDocPropSlice[T json.Number | int | float64 | bool | string](docs []map[string]any, propName string, size int) []*T { |
| 1101 | + values := make([]*T, size) |
| 1102 | + |
1081 | 1103 | for i, doc := range docs {
|
1082 | 1104 | value, ok := doc[propName].(T)
|
1083 | 1105 | if !ok {
|
1084 | 1106 | continue
|
1085 | 1107 | }
|
1086 |
| - fieldVector[i] = &value |
| 1108 | + values[i] = &value |
1087 | 1109 | }
|
| 1110 | + |
| 1111 | + return values |
| 1112 | +} |
| 1113 | + |
| 1114 | +func createFieldOfType[T int | float64 | bool | string](fieldVector []*T, propName string, size int, isFilterable bool) *data.Field { |
1088 | 1115 | field := data.NewField(propName, nil, fieldVector)
|
1089 | 1116 | field.Config = &data.FieldConfig{Filterable: &isFilterable}
|
1090 | 1117 | return field
|
|
0 commit comments