From 47c18684d336886726fbc0cc4142c29fb39c62c1 Mon Sep 17 00:00:00 2001 From: Idriss Neumann Date: Tue, 28 Nov 2023 08:20:25 +0100 Subject: [PATCH] Issue #18: searching keyword to highlight from the backend side --- pkg/quickwit/response_parser.go | 43 ++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/pkg/quickwit/response_parser.go b/pkg/quickwit/response_parser.go index 818d0bc..dc5667d 100644 --- a/pkg/quickwit/response_parser.go +++ b/pkg/quickwit/response_parser.go @@ -95,11 +95,32 @@ func parseResponse(responses []*es.SearchResponse, targets []*Query, configuredF return &result, nil } +func parseLuceneQuery(query string) []string { + var keywords []string + + // Extract terms and phrases + termRegex := regexp.MustCompile(`("[^"]+"|\S+)`) + matches := termRegex.FindAllString(query, -1) + + for _, match := range matches { + // Remove quotes from phrases + if match[0] == '"' && match[len(match)-1] == '"' { + keywords = append(keywords, match[1:len(match)-1]) + } else { + keywords = append(keywords, match) + } + } + + return keywords +} + func processLogsResponse(res *es.SearchResponse, target *Query, configuredFields es.ConfiguredFields, queryRes *backend.DataResponse) error { propNames := make(map[string]bool) docs := make([]map[string]interface{}, len(res.Hits.Hits)) searchWords := make(map[string]bool) + highlights := parseLuceneQuery(target.RawQuery) + for hitIdx, hit := range res.Hits.Hits { var flattened map[string]interface{} if hit["_source"] != nil { @@ -132,23 +153,6 @@ func processLogsResponse(res *es.SearchResponse, target *Query, configuredFields propNames[key] = true } - // FIXME: Quickwit does not support highlight. Should we replace this by a custom highlighter? - // Process highlight to searchWords - if highlights, ok := doc["highlight"].(map[string]interface{}); ok { - for _, highlight := range highlights { - if highlightList, ok := highlight.([]interface{}); ok { - for _, highlightValue := range highlightList { - str := fmt.Sprintf("%v", highlightValue) - matches := searchWordsRegex.FindAllStringSubmatch(str, -1) - - for _, v := range matches { - searchWords[v[1]] = true - } - } - } - } - } - docs[hitIdx] = doc } @@ -158,6 +162,11 @@ func processLogsResponse(res *es.SearchResponse, target *Query, configuredFields frames := data.Frames{} frame := data.NewFrame("", fields...) setPreferredVisType(frame, data.VisTypeLogs) + + for _, keyword := range highlights { + searchWords[keyword] = true + } + setLogsCustomMeta(frame, searchWords, stringToIntWithDefaultValue(target.Metrics[0].Settings.Get("limit").MustString(), defaultSize)) frames = append(frames, frame)