Skip to content

Commit 4a37634

Browse files
committed
Refactor highlighting logic into util class
1 parent 9c7609c commit 4a37634

File tree

3 files changed

+76
-22
lines changed

3 files changed

+76
-22
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.search.fetch.subphase.highlight;
11+
12+
import org.apache.lucene.search.Query;
13+
import org.elasticsearch.index.query.QueryBuilder;
14+
import org.elasticsearch.index.query.SearchExecutionContext;
15+
16+
import java.io.IOException;
17+
import java.util.List;
18+
19+
/**
20+
* Utility class for building highlighting queries for the purpose of extracting snippets.
21+
*/
22+
public class HighlightSnippetUtils {
23+
24+
public static SearchHighlightContext buildSearchHighlightContextForSnippets(
25+
SearchExecutionContext searchExecutionContext,
26+
String field,
27+
int numSnippets,
28+
int snippetCharLength,
29+
QueryBuilder queryBuilder
30+
) throws IOException {
31+
SearchHighlightContext.Field highlightField = buildFieldHighlightContextForSnippets(
32+
searchExecutionContext,
33+
field,
34+
numSnippets,
35+
snippetCharLength,
36+
queryBuilder.toQuery(searchExecutionContext)
37+
);
38+
return new SearchHighlightContext(List.of(highlightField));
39+
}
40+
41+
public static SearchHighlightContext.Field buildFieldHighlightContextForSnippets(
42+
SearchExecutionContext searchExecutionContext,
43+
String fieldName,
44+
int numSnippets,
45+
int snippetCharLength,
46+
Query query
47+
) {
48+
SearchHighlightContext.FieldOptions.Builder optionsBuilder = new SearchHighlightContext.FieldOptions.Builder();
49+
optionsBuilder.numberOfFragments(numSnippets);
50+
optionsBuilder.fragmentCharSize(snippetCharLength);
51+
optionsBuilder.noMatchSize(snippetCharLength);
52+
optionsBuilder.preTags(new String[] { "" });
53+
optionsBuilder.postTags(new String[] { "" });
54+
optionsBuilder.requireFieldMatch(false);
55+
optionsBuilder.scoreOrdered(true);
56+
optionsBuilder.highlightQuery(query);
57+
return new SearchHighlightContext.Field(fieldName, optionsBuilder.build());
58+
}
59+
60+
}

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/lucene/HighlighterExpressionEvaluator.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.elasticsearch.search.fetch.subphase.highlight.FieldHighlightContext;
3131
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
3232
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
33+
import org.elasticsearch.search.fetch.subphase.highlight.HighlightSnippetUtils;
3334
import org.elasticsearch.search.fetch.subphase.highlight.Highlighter;
3435
import org.elasticsearch.search.fetch.subphase.highlight.SearchHighlightContext;
3536
import org.elasticsearch.search.internal.SearchContext;
@@ -106,17 +107,13 @@ protected void appendMatch(BytesRefBlock.Builder builder, Scorable scorer, int d
106107
Source source = Source.lazy(lazyStoredSourceLoader(leafReaderContext, docId));
107108
Highlighter highlighter = highlighters.getOrDefault(fieldType.getDefaultHighlighter(), new DefaultHighlighter());
108109

109-
// TODO: Consolidate these options with the ones built in the text similarity reranker
110-
SearchHighlightContext.FieldOptions.Builder optionsBuilder = new SearchHighlightContext.FieldOptions.Builder();
111-
optionsBuilder.numberOfFragments(numFragments != null ? numFragments : HighlightBuilder.DEFAULT_NUMBER_OF_FRAGMENTS);
112-
optionsBuilder.fragmentCharSize(fragmentLength != null ? fragmentLength : HighlightBuilder.DEFAULT_FRAGMENT_CHAR_SIZE);
113-
optionsBuilder.preTags(new String[] { "" });
114-
optionsBuilder.postTags(new String[] { "" });
115-
optionsBuilder.requireFieldMatch(false);
116-
optionsBuilder.scoreOrdered(true);
117-
optionsBuilder.highlightQuery(query);
118-
SearchHighlightContext.Field field = new SearchHighlightContext.Field(fieldName, optionsBuilder.build());
119-
110+
SearchHighlightContext.Field field = HighlightSnippetUtils.buildFieldHighlightContextForSnippets(
111+
fetchContext.getSearchExecutionContext(),
112+
fieldName,
113+
numFragments != null ? numFragments : HighlightBuilder.DEFAULT_NUMBER_OF_FRAGMENTS,
114+
fragmentLength != null ? fragmentLength : HighlightBuilder.DEFAULT_FRAGMENT_CHAR_SIZE,
115+
query
116+
);
120117
FetchSubPhase.HitContext hitContext = new FetchSubPhase.HitContext(searchHit, leafReaderContext, docId, Map.of(), source, null);
121118
FieldHighlightContext highlightContext = new FieldHighlightContext(
122119
fieldName,

x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRerankingRankFeaturePhaseRankShardContext.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
import org.elasticsearch.core.Nullable;
1313
import org.elasticsearch.search.SearchHit;
1414
import org.elasticsearch.search.SearchHits;
15-
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
1615
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
16+
import org.elasticsearch.search.fetch.subphase.highlight.HighlightSnippetUtils;
1717
import org.elasticsearch.search.fetch.subphase.highlight.SearchHighlightContext;
1818
import org.elasticsearch.search.internal.SearchContext;
1919
import org.elasticsearch.search.rank.RankShardResult;
@@ -73,20 +73,17 @@ public RankShardResult doBuildRankFeatureShardResult(SearchHits hits, int shardI
7373
public void prepareForFetch(SearchContext context) {
7474
if (snippetRankInput != null) {
7575
try {
76-
HighlightBuilder highlightBuilder = new HighlightBuilder();
77-
highlightBuilder.highlightQuery(snippetRankInput.snippetQueryBuilder());
78-
// Stripping pre/post tags as they're not useful for snippet creation
79-
highlightBuilder.field(field).preTags("").postTags("");
80-
// Return highest scoring fragments
81-
highlightBuilder.order(HighlightBuilder.Order.SCORE);
8276
int numSnippets = snippetRankInput.numSnippets() != null ? snippetRankInput.numSnippets() : DEFAULT_NUM_SNIPPETS;
83-
highlightBuilder.numOfFragments(numSnippets);
8477
// Rely on the model to determine the fragment size
8578
int tokenSizeLimit = snippetRankInput.tokenSizeLimit();
8679
int fragmentSize = tokenSizeLimit * TOKEN_SIZE_LIMIT_MULTIPLIER;
87-
highlightBuilder.fragmentSize(fragmentSize);
88-
highlightBuilder.noMatchSize(fragmentSize);
89-
SearchHighlightContext searchHighlightContext = highlightBuilder.build(context.getSearchExecutionContext());
80+
SearchHighlightContext searchHighlightContext = HighlightSnippetUtils.buildSearchHighlightContextForSnippets(
81+
context.getSearchExecutionContext(),
82+
field,
83+
numSnippets,
84+
fragmentSize,
85+
snippetRankInput.snippetQueryBuilder()
86+
);
9087
context.highlight(searchHighlightContext);
9188
} catch (IOException e) {
9289
throw new RuntimeException("Failed to generate snippet request", e);

0 commit comments

Comments
 (0)