Skip to content

Commit b71b27a

Browse files
committed
Issue #18: searching keyword to highlight from the backend side
1 parent abd7860 commit b71b27a

File tree

2 files changed

+54
-17
lines changed

2 files changed

+54
-17
lines changed

Diff for: pkg/quickwit/response_parser.go

+24-17
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,30 @@ func parseResponse(responses []*es.SearchResponse, targets []*Query, configuredF
9595
return &result, nil
9696
}
9797

98+
func parseLuceneQuery(query string) []string {
99+
var keywords []string
100+
101+
termRegex := regexp.MustCompile(`("[^"]+"|\S+)`)
102+
matches := termRegex.FindAllString(query, -1)
103+
104+
for _, match := range matches {
105+
if match[0] == '"' && match[len(match)-1] == '"' {
106+
match = match[1 : len(match)-1]
107+
}
108+
109+
keywords = append(keywords, strings.ReplaceAll(match, "*", ""))
110+
}
111+
112+
return keywords
113+
}
114+
98115
func processLogsResponse(res *es.SearchResponse, target *Query, configuredFields es.ConfiguredFields, queryRes *backend.DataResponse) error {
99116
propNames := make(map[string]bool)
100117
docs := make([]map[string]interface{}, len(res.Hits.Hits))
101118
searchWords := make(map[string]bool)
102119

120+
highlights := parseLuceneQuery(target.RawQuery)
121+
103122
for hitIdx, hit := range res.Hits.Hits {
104123
var flattened map[string]interface{}
105124
if hit["_source"] != nil {
@@ -132,23 +151,6 @@ func processLogsResponse(res *es.SearchResponse, target *Query, configuredFields
132151
propNames[key] = true
133152
}
134153

135-
// FIXME: Quickwit does not support highlight. Should we replace this by a custom highlighter?
136-
// Process highlight to searchWords
137-
if highlights, ok := doc["highlight"].(map[string]interface{}); ok {
138-
for _, highlight := range highlights {
139-
if highlightList, ok := highlight.([]interface{}); ok {
140-
for _, highlightValue := range highlightList {
141-
str := fmt.Sprintf("%v", highlightValue)
142-
matches := searchWordsRegex.FindAllStringSubmatch(str, -1)
143-
144-
for _, v := range matches {
145-
searchWords[v[1]] = true
146-
}
147-
}
148-
}
149-
}
150-
}
151-
152154
docs[hitIdx] = doc
153155
}
154156

@@ -158,6 +160,11 @@ func processLogsResponse(res *es.SearchResponse, target *Query, configuredFields
158160
frames := data.Frames{}
159161
frame := data.NewFrame("", fields...)
160162
setPreferredVisType(frame, data.VisTypeLogs)
163+
164+
for _, keyword := range highlights {
165+
searchWords[keyword] = true
166+
}
167+
161168
setLogsCustomMeta(frame, searchWords, stringToIntWithDefaultValue(target.Metrics[0].Settings.Get("limit").MustString(), defaultSize))
162169
frames = append(frames, frame)
163170

Diff for: pkg/quickwit/response_parser_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -3178,6 +3178,36 @@ func TestLabelOrderInFieldName(t *testing.T) {
31783178
requireTimeSeriesName(t, "val1 error", frames[5])
31793179
}
31803180

3181+
func TestParseLuceneQuery(t *testing.T) {
3182+
t.Run("Empty term query", func(t *testing.T) {
3183+
query := ""
3184+
highlights := parseLuceneQuery(query)
3185+
require.Len(t, highlights, 0)
3186+
})
3187+
3188+
t.Run("Simple term query", func(t *testing.T) {
3189+
query := "foo"
3190+
highlights := parseLuceneQuery(query)
3191+
require.Len(t, highlights, 1)
3192+
require.Equal(t, "foo", highlights[0])
3193+
})
3194+
3195+
t.Run("Multi term query", func(t *testing.T) {
3196+
query := "foo bar"
3197+
highlights := parseLuceneQuery(query)
3198+
require.Len(t, highlights, 2)
3199+
require.Equal(t, "foo", highlights[0])
3200+
require.Equal(t, "bar", highlights[1])
3201+
})
3202+
3203+
t.Run("Wildcard query", func(t *testing.T) {
3204+
query := "foo*"
3205+
highlights := parseLuceneQuery(query)
3206+
require.Len(t, highlights, 1)
3207+
require.Equal(t, "foo", highlights[0])
3208+
})
3209+
}
3210+
31813211
func TestFlatten(t *testing.T) {
31823212
t.Run("Flattens simple object", func(t *testing.T) {
31833213
obj := map[string]interface{}{

0 commit comments

Comments
 (0)