Skip to content

Commit 05be98b

Browse files
feature: add highlight query support (#71)
Implement highlight configuration with full DSL support including: highlightType (global settings): - PreTags, PostTags for custom highlight markers - Field for adding field-specific highlight configurations - Type (unified, plain, fvh) for highlighter selection - Order, Encoder, RequireFieldMatch - FragmentSize, NumberOfFragments, NoMatchSize - BoundaryScanner, BoundaryChars, BoundaryMaxScan, BoundaryScannerLocale - Fragmenter, FragmentOffset, MaxFragmentLength, MaxAnalyzedOffset - HighlightQuery for custom highlight queries - TagsSchema for built-in tag schemas highlightFieldType (per-field settings): - PreTags, PostTags, Type, Order - FragmentSize, NumberOfFragments, NoMatchSize - HighlightQuery, RequireFieldMatch, Fragmenter, MatchedFields Object.Highlight method added to base_query.go for top-level query integration. New enums: - highlighter-type: unified, plain, fvh - boundary-scanner: chars, sentence, word - fragmenter: simple, span All implementations follow existing project conventions and patterns. * test: add nil query handling test for HighlightField.HighlightQuery
1 parent 244418f commit 05be98b

9 files changed

Lines changed: 1842 additions & 0 deletions

File tree

es/base_query.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,34 @@ func (o Object) Sort(sorts ...sortType) Object {
218218
return o
219219
}
220220

221+
// Highlight sets the "highlight" parameter in an es.Object.
222+
//
223+
// This method allows you to specify highlighting configuration for the search query.
224+
// Highlighting enables you to get highlighted snippets from one or more fields in your
225+
// search results so you can show users where the query matches are.
226+
//
227+
// Example usage:
228+
//
229+
// query := es.NewQuery(es.MatchAll()).
230+
// Highlight(
231+
// es.Highlight().
232+
// PreTags("<em>").
233+
// PostTags("</em>").
234+
// Field(es.HighlightField("title")),
235+
// )
236+
// // query now includes a "highlight" parameter with the specified configuration.
237+
//
238+
// Parameters:
239+
// - highlight: An es.highlightType object representing the highlight configuration.
240+
//
241+
// Returns:
242+
//
243+
// The updated es.Object with the "highlight" parameter set.
244+
func (o Object) Highlight(highlight highlightType) Object {
245+
o["highlight"] = highlight
246+
return o
247+
}
248+
221249
// Aggs adds one or more es.aggsType objects to an es.Object.
222250
//
223251
// This method allows you to specify multiple aggregation criteria for the search query.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package boundaryscanner
2+
3+
// BoundaryScanner represents the different boundary scanner types for highlighting in Elasticsearch.
4+
//
5+
// BoundaryScanner is a string type used to specify how highlighted fragments are bounded.
6+
// It determines the strategy for finding the boundaries of highlighted snippets.
7+
//
8+
// Example usage:
9+
//
10+
// var bs BoundaryScanner = Sentence
11+
//
12+
// // Use bs in a highlight configuration
13+
//
14+
// Constants:
15+
// - Chars: The chars boundary scanner breaks highlighted fragments at characters specified by boundary_chars.
16+
// - Sentence: The sentence boundary scanner breaks highlighted fragments at the next sentence boundary.
17+
// - Word: The word boundary scanner breaks highlighted fragments at the next word boundary.
18+
type BoundaryScanner string
19+
20+
const (
21+
// Chars indicates that the boundary scanner should break at specified boundary characters.
22+
Chars BoundaryScanner = "chars"
23+
24+
// Sentence indicates that the boundary scanner should break at sentence boundaries.
25+
Sentence BoundaryScanner = "sentence"
26+
27+
// Word indicates that the boundary scanner should break at word boundaries.
28+
Word BoundaryScanner = "word"
29+
)
30+
31+
func (boundaryScanner BoundaryScanner) String() string {
32+
return string(boundaryScanner)
33+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package boundaryscanner_test
2+
3+
import (
4+
"testing"
5+
6+
BoundaryScanner "github.com/Trendyol/es-query-builder/es/enums/boundary-scanner"
7+
8+
"github.com/Trendyol/es-query-builder/test/assert"
9+
)
10+
11+
func Test_BoundaryScannerString(t *testing.T) {
12+
tests := []struct {
13+
boundaryScanner BoundaryScanner.BoundaryScanner
14+
result string
15+
}{
16+
{BoundaryScanner.Chars, "chars"},
17+
{BoundaryScanner.Sentence, "sentence"},
18+
{BoundaryScanner.Word, "word"},
19+
}
20+
21+
for _, test := range tests {
22+
t.Run(test.result, func(t *testing.T) {
23+
assert.Equal(t, test.result, test.boundaryScanner.String())
24+
})
25+
}
26+
}

es/enums/fragmenter/fragmenter.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package fragmenter
2+
3+
// Fragmenter represents the different fragmenter types for highlighting in Elasticsearch.
4+
//
5+
// Fragmenter is a string type used to specify how text should be broken up into
6+
// highlight fragments. It determines the strategy for creating text fragments
7+
// that contain highlighted terms.
8+
//
9+
// Example usage:
10+
//
11+
// var f Fragmenter = Span
12+
//
13+
// // Use f in a highlight configuration
14+
//
15+
// Constants:
16+
// - Simple: The simple fragmenter breaks text into same-sized fragments.
17+
// - Span: The span fragmenter breaks text into same-sized fragments, but tries to avoid breaking up highlighted terms.
18+
type Fragmenter string
19+
20+
const (
21+
// Simple indicates that text should be broken into same-sized fragments.
22+
Simple Fragmenter = "simple"
23+
24+
// Span indicates that text should be broken into same-sized fragments while trying to avoid breaking highlighted terms.
25+
Span Fragmenter = "span"
26+
)
27+
28+
func (fragmenter Fragmenter) String() string {
29+
return string(fragmenter)
30+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package fragmenter_test
2+
3+
import (
4+
"testing"
5+
6+
Fragmenter "github.com/Trendyol/es-query-builder/es/enums/fragmenter"
7+
8+
"github.com/Trendyol/es-query-builder/test/assert"
9+
)
10+
11+
func Test_FragmenterString(t *testing.T) {
12+
tests := []struct {
13+
fragmenter Fragmenter.Fragmenter
14+
result string
15+
}{
16+
{Fragmenter.Simple, "simple"},
17+
{Fragmenter.Span, "span"},
18+
}
19+
20+
for _, test := range tests {
21+
t.Run(test.result, func(t *testing.T) {
22+
assert.Equal(t, test.result, test.fragmenter.String())
23+
})
24+
}
25+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package highlightertype
2+
3+
// HighlighterType represents the different highlighter types available in Elasticsearch.
4+
//
5+
// HighlighterType is a string type used to specify which highlighter implementation
6+
// to use for highlighting search results. Elasticsearch provides three highlighter
7+
// implementations: unified, plain, and fvh (Fast Vector Highlighter).
8+
//
9+
// Example usage:
10+
//
11+
// var ht HighlighterType = Unified
12+
//
13+
// // Use ht in a highlight configuration
14+
//
15+
// Constants:
16+
// - Unified: The unified highlighter uses the Lucene Unified Highlighter (default).
17+
// - Plain: The plain highlighter uses the standard Lucene highlighter.
18+
// - Fvh: The fvh (Fast Vector Highlighter) highlighter uses the Lucene Fast Vector Highlighter.
19+
type HighlighterType string
20+
21+
const (
22+
// Unified indicates the unified highlighter, which is the default highlighter in Elasticsearch.
23+
Unified HighlighterType = "unified"
24+
25+
// Plain indicates the plain highlighter, which uses the standard Lucene highlighter.
26+
Plain HighlighterType = "plain"
27+
28+
// Fvh indicates the Fast Vector Highlighter, which requires term_vector set to with_positions_offsets.
29+
Fvh HighlighterType = "fvh"
30+
)
31+
32+
func (highlighterType HighlighterType) String() string {
33+
return string(highlighterType)
34+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package highlightertype_test
2+
3+
import (
4+
"testing"
5+
6+
HighlighterType "github.com/Trendyol/es-query-builder/es/enums/highlighter-type"
7+
8+
"github.com/Trendyol/es-query-builder/test/assert"
9+
)
10+
11+
func Test_HighlighterTypeString(t *testing.T) {
12+
tests := []struct {
13+
highlighterType HighlighterType.HighlighterType
14+
result string
15+
}{
16+
{HighlighterType.Unified, "unified"},
17+
{HighlighterType.Plain, "plain"},
18+
{HighlighterType.Fvh, "fvh"},
19+
}
20+
21+
for _, test := range tests {
22+
t.Run(test.result, func(t *testing.T) {
23+
assert.Equal(t, test.result, test.highlighterType.String())
24+
})
25+
}
26+
}

0 commit comments

Comments
 (0)