Skip to content

Commit 36fe8eb

Browse files
committed
added edge case to tests
1 parent 2e90d6d commit 36fe8eb

File tree

2 files changed

+131
-21
lines changed

2 files changed

+131
-21
lines changed

server/src/internalClusterTest/java/org/elasticsearch/search/fetch/subphase/highlight/HighlighterSearchIT.java

Lines changed: 85 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
*/
88
package org.elasticsearch.search.fetch.subphase.highlight;
99

10-
import net.bytebuddy.utility.RandomString;
11-
1210
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
1311

1412
import org.apache.lucene.analysis.Analyzer;
@@ -3506,9 +3504,8 @@ public void testDisableHighlightIdField() throws Exception {
35063504
public void testConstantKeywordFieldHighlighting() throws IOException {
35073505
// check that constant_keyword highlighting works
35083506
String index = "test";
3509-
RandomString randomStringGenerator = new RandomString(5);
3510-
String constantKeywordFieldName = randomStringGenerator.nextString();
3511-
String constantValue = randomStringGenerator.nextString();
3507+
String constantKeywordFieldName = "test_constant_keyword_field";
3508+
String constantValue = "constant_value";
35123509

35133510
XContentBuilder mappings = prepareConstantKeywordMappings(constantKeywordFieldName, constantValue);
35143511
assertAcked(prepareCreate(index).setMapping(mappings));
@@ -3528,9 +3525,8 @@ public void testConstantKeywordFieldHighlighting() throws IOException {
35283525
public void testImplicitConstantKeywordFieldHighlighting() throws IOException {
35293526
// Constant field value is defined by the mapping
35303527
String index = "test";
3531-
RandomString randomStringGenerator = new RandomString(5);
3532-
String constantKeywordFieldName = randomStringGenerator.nextString();
3533-
String constantValue = randomStringGenerator.nextString();
3528+
String constantKeywordFieldName = "test_constant_keyword_field";
3529+
String constantValue = "constant_value";
35343530

35353531
XContentBuilder mappings = prepareConstantKeywordMappings(constantKeywordFieldName, constantValue);
35363532
assertAcked(prepareCreate(index).setMapping(mappings));
@@ -3546,9 +3542,8 @@ public void testImplicitConstantKeywordFieldHighlighting() throws IOException {
35463542

35473543
public void testConstantKeywordFieldPartialNoHighlighting() throws IOException {
35483544
String index = "test";
3549-
RandomString randomStringGenerator = new RandomString(5);
3550-
String constantKeywordFieldName = randomStringGenerator.nextString();
3551-
String constantValue = randomStringGenerator.nextString();
3545+
String constantKeywordFieldName = "test_constant_keyword_field";
3546+
String constantValue = "constant_value";
35523547
String partialConstantValue = constantValue.substring(0, 3);
35533548

35543549
XContentBuilder mappings = prepareConstantKeywordMappings(constantKeywordFieldName, constantValue);
@@ -3565,9 +3560,8 @@ public void testConstantKeywordFieldPartialNoHighlighting() throws IOException {
35653560

35663561
public void testConstantKeywordFieldPartialWithWildcardHighlighting() throws IOException {
35673562
String index = "test";
3568-
RandomString randomStringGenerator = new RandomString(5);
3569-
String constantKeywordFieldName = randomStringGenerator.nextString();
3570-
String constantValue = randomStringGenerator.nextString();
3563+
String constantKeywordFieldName = "test_constant_keyword_field";
3564+
String constantValue = "constant_value";
35713565
String partialConstantValueWithWildCard = "%s*".formatted(constantValue.substring(0, 3));
35723566

35733567
XContentBuilder mappings = prepareConstantKeywordMappings(constantKeywordFieldName, constantValue);
@@ -3582,6 +3576,83 @@ public void testConstantKeywordFieldPartialWithWildcardHighlighting() throws IOE
35823576
assertHighlight(search, 0, constantKeywordFieldName, 0, 1, equalTo("<em>%s</em>".formatted(constantValue)));
35833577
}
35843578

3579+
public void testConstantKeywordFieldNotHighlightedOnOtherFieldMatch() throws IOException {
3580+
String index = "test";
3581+
String constantKeywordFieldName = "test_constant_keyword_field";
3582+
String constantValue = "constant_value";
3583+
3584+
XContentBuilder mappings = prepareConstantKeywordMappings(constantKeywordFieldName, constantValue);
3585+
assertAcked(prepareCreate(index).setMapping(mappings));
3586+
3587+
XContentBuilder document = jsonBuilder().startObject().field("foo", "bar").endObject();
3588+
saveDocumentIntoIndex(index, "1", document);
3589+
3590+
SearchResponse search = prepareConstantKeywordSearch(QueryBuilders.termQuery("foo", "bar"));
3591+
3592+
assertNoFailures(search);
3593+
assertEquals(1, search.getHits().getHits()[0].getHighlightFields().size());
3594+
}
3595+
3596+
public void testConstantKeywordFieldAndOtherFieldsMatchHighlighted() throws IOException {
3597+
String index = "test";
3598+
String constantKeywordFieldName = "test_constant_keyword_field";
3599+
String constantValue = "bar";
3600+
3601+
XContentBuilder mappings = prepareConstantKeywordMappings(constantKeywordFieldName, constantValue);
3602+
assertAcked(prepareCreate(index).setMapping(mappings));
3603+
3604+
XContentBuilder document = jsonBuilder().startObject().field("foo", constantValue).endObject();
3605+
saveDocumentIntoIndex(index, "1", document);
3606+
3607+
SearchResponse search = prepareConstantKeywordSearch(QueryBuilders.queryStringQuery(constantValue));
3608+
3609+
assertNoFailures(search);
3610+
assertHighlight(search, 0, constantKeywordFieldName, 0, 1, equalTo("<em>%s</em>".formatted(constantValue)));
3611+
assertHighlight(search, 0, "foo", 0, 1, equalTo("<em>%s</em>".formatted(constantValue)));
3612+
3613+
}
3614+
3615+
public void testConstantKeywordMultipleHitsHighlighted() throws IOException {
3616+
String index = "test";
3617+
String constantKeywordFieldName = "test_constant_keyword_field";
3618+
String constantValue = "constant_value";
3619+
3620+
XContentBuilder mappings = prepareConstantKeywordMappings(constantKeywordFieldName, constantValue);
3621+
assertAcked(prepareCreate(index).setMapping(mappings));
3622+
3623+
XContentBuilder firstDocument = jsonBuilder().startObject().field("foo", "bar").endObject();
3624+
XContentBuilder secondDocument = jsonBuilder().startObject().field("foo", "baz").endObject();
3625+
saveDocumentIntoIndex(index, "1", firstDocument);
3626+
saveDocumentIntoIndex(index, "2", secondDocument);
3627+
3628+
SearchResponse search = prepareConstantKeywordSearch(QueryBuilders.queryStringQuery(constantValue));
3629+
3630+
assertNoFailures(search);
3631+
assertHighlight(search, 0, constantKeywordFieldName, 0, 1, equalTo("<em>%s</em>".formatted(constantValue)));
3632+
assertHighlight(search, 1, constantKeywordFieldName, 0, 1, equalTo("<em>%s</em>".formatted(constantValue)));
3633+
}
3634+
3635+
public void testConstantKeywordAndOtherFieldsMatchMultipleHitsHighlighted() throws IOException {
3636+
String index = "test";
3637+
String constantKeywordFieldName = "test_constant_keyword_field";
3638+
String constantValue = "constant_value";
3639+
3640+
XContentBuilder mappings = prepareConstantKeywordMappings(constantKeywordFieldName, constantValue);
3641+
assertAcked(prepareCreate(index).setMapping(mappings));
3642+
3643+
XContentBuilder firstDocument = jsonBuilder().startObject().field("foo", "bar").endObject();
3644+
XContentBuilder secondDocument = jsonBuilder().startObject().field("foo", constantValue).endObject();
3645+
saveDocumentIntoIndex(index, "1", firstDocument);
3646+
saveDocumentIntoIndex(index, "2", secondDocument);
3647+
3648+
SearchResponse search = prepareConstantKeywordSearch(QueryBuilders.queryStringQuery(constantValue));
3649+
3650+
assertNoFailures(search);
3651+
assertHighlight(search, 0, constantKeywordFieldName, 0, 1, equalTo("<em>%s</em>".formatted(constantValue)));
3652+
assertHighlight(search, 1, "foo", 0, 1, equalTo("<em>%s</em>".formatted(constantValue)));
3653+
assertHighlight(search, 1, constantKeywordFieldName, 0, 1, equalTo("<em>%s</em>".formatted(constantValue)));
3654+
}
3655+
35853656
private XContentBuilder prepareConstantKeywordMappings(String constantKeywordFieldName, String constantValue) throws IOException {
35863657
XContentBuilder mappings = jsonBuilder();
35873658
mappings.startObject();

server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightPhase.java

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010

1111
import org.apache.lucene.index.LeafReaderContext;
1212
import org.apache.lucene.index.Term;
13+
import org.apache.lucene.search.DisjunctionMaxQuery;
14+
import org.apache.lucene.search.MatchAllDocsQuery;
15+
import org.apache.lucene.search.MatchNoDocsQuery;
1316
import org.apache.lucene.search.Query;
1417
import org.apache.lucene.search.TermQuery;
1518
import org.elasticsearch.index.mapper.ConstantFieldType;
@@ -117,7 +120,7 @@ private FieldContext contextBuilders(
117120
MappedFieldType fieldType = context.getSearchExecutionContext().getFieldType(fieldName);
118121

119122
// We should prevent highlighting if a field is anything but a text, match_only_text,
120-
// or keyword field.
123+
// keyword or constant_keyword field.
121124
// However, someone might implement a custom field type that has text and still want to
122125
// highlight on that. We cannot know in advance if the highlighter will be able to
123126
// highlight such a field and so we do the following:
@@ -143,11 +146,27 @@ private FieldContext contextBuilders(
143146
sourceRequired = true;
144147
}
145148

146-
Query highlightQuery = field.fieldOptions().highlightQuery();
147-
if (fieldType instanceof ConstantFieldType) {
148-
highlightQuery = new TermQuery(new Term(fieldType.name(), getValueForConstantFieldType(context, fieldType)));
149-
}
150-
Query finalHighlightQuery = highlightQuery;
149+
// Query highlightQuery = field.fieldOptions().highlightQuery();
150+
// if (fieldType instanceof ConstantFieldType) {
151+
// if (context.query() instanceof MatchAllDocsQuery ){
152+
// highlightQuery = new TermQuery(new Term(fieldType.name(), getValueForConstantFieldType(context, fieldType)));
153+
// } else if (context.query() instanceof DisjunctionMaxQuery) {
154+
// DisjunctionMaxQuery disjunctionMaxQuery = (DisjunctionMaxQuery) context.query();
155+
// for (Query anyQuery : disjunctionMaxQuery.getDisjuncts()) {
156+
// if (anyQuery instanceof MatchAllDocsQuery){
157+
// highlightQuery = new TermQuery(new Term(fieldType.name(), getValueForConstantFieldType(context, fieldType)));
158+
// }
159+
// }
160+
// }
161+
// }
162+
//// if (((ConstantFieldType)fieldType).termQuery(getValueForConstantFieldType(context, fieldType),
163+
// context.getSearchExecutionContext()) instanceof MatchAllDocsQuery) {
164+
//// highlightQuery = new TermQuery(new Term(fieldType.name(), getValueForConstantFieldType(context, fieldType)));
165+
//// }
166+
//// }
167+
// Query finalHighlightQuery = highlightQuery;
168+
Query highlightQuery = getHighlighterQuery(context, field, fieldType);
169+
151170
builders.put(
152171
fieldName,
153172
hc -> new FieldHighlightContext(
@@ -156,7 +175,7 @@ private FieldContext contextBuilders(
156175
fieldType,
157176
context,
158177
hc,
159-
finalHighlightQuery == null ? query : finalHighlightQuery,
178+
highlightQuery == null ? query : highlightQuery,
160179
sharedCache
161180
)
162181
);
@@ -166,6 +185,26 @@ private FieldContext contextBuilders(
166185
return new FieldContext(storedFieldsSpec, builders);
167186
}
168187

188+
private Query getHighlighterQuery(FetchContext context, SearchHighlightContext.Field field, MappedFieldType fieldType) {
189+
if (fieldType instanceof ConstantFieldType) {
190+
return getHighlighterQueryForConstantFieldType(context, fieldType);
191+
}
192+
return field.fieldOptions().highlightQuery();
193+
}
194+
195+
private Query getHighlighterQueryForConstantFieldType(FetchContext context, MappedFieldType fieldType) {
196+
if (context.query() instanceof MatchAllDocsQuery) {
197+
return new TermQuery(new Term(fieldType.name(), getValueForConstantFieldType(context, fieldType)));
198+
} else if (context.query() instanceof DisjunctionMaxQuery disjunctionMaxQuery) {
199+
for (Query anyDisjunctQuery : disjunctionMaxQuery.getDisjuncts()) {
200+
if (anyDisjunctQuery instanceof MatchAllDocsQuery) {
201+
return new TermQuery(new Term(fieldType.name(), getValueForConstantFieldType(context, fieldType)));
202+
}
203+
}
204+
}
205+
return new MatchNoDocsQuery();
206+
}
207+
169208
private String getValueForConstantFieldType(FetchContext context, MappedFieldType fieldType) {
170209
try {
171210
return (String) fieldType.valueFetcher(context.getSearchExecutionContext(), null).fetchValues(null, 0, List.of()).get(0);

0 commit comments

Comments
 (0)