|
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