use of org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder.Field in project elasticsearch by elastic.
the class HighlighterSearchIT method testFiltersFunctionScoreQueryHighlight.
public void testFiltersFunctionScoreQueryHighlight() throws Exception {
client().prepareIndex("test", "type", "1").setSource(jsonBuilder().startObject().field("text", "brown").field("enable", "yes").endObject()).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).get();
FunctionScoreQueryBuilder.FilterFunctionBuilder filterBuilder = new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery("enable", "yes"), new RandomScoreFunctionBuilder());
for (String type : UNIFIED_AND_NULL) {
SearchResponse searchResponse = client().prepareSearch().setQuery(new FunctionScoreQueryBuilder(QueryBuilders.prefixQuery("text", "bro"), new FunctionScoreQueryBuilder.FilterFunctionBuilder[] { filterBuilder })).highlighter(new HighlightBuilder().field(new Field("text")).highlighterType(type)).get();
assertHitCount(searchResponse, 1);
HighlightField field = searchResponse.getHits().getAt(0).getHighlightFields().get("text");
assertThat(field.getFragments().length, equalTo(1));
assertThat(field.getFragments()[0].string(), equalTo("<em>brown</em>"));
}
}
use of org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder.Field in project elasticsearch by elastic.
the class HighlighterSearchIT method testHighlightNoMatchSizeNumberOfFragments.
public void testHighlightNoMatchSizeNumberOfFragments() throws IOException {
assertAcked(prepareCreate("test").addMapping("type1", "text", "type=text," + randomStoreField() + "term_vector=with_positions_offsets,index_options=offsets"));
ensureGreen();
String text1 = "This is the first sentence. This is the second sentence." + HighlightUtils.PARAGRAPH_SEPARATOR;
String text2 = "This is the third sentence. This is the fourth sentence.";
String text3 = "This is the fifth sentence";
index("test", "type1", "1", "text", new String[] { text1, text2, text3 });
refresh();
// The no match fragment should come from the first value of a multi-valued field
HighlightBuilder.Field field = new HighlightBuilder.Field("text").fragmentSize(1).numOfFragments(0).highlighterType("plain").noMatchSize(20);
SearchResponse response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get();
assertHighlight(response, 0, "text", 0, 1, equalTo("This is the first"));
field.highlighterType("fvh");
response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get();
assertHighlight(response, 0, "text", 0, 1, equalTo("This is the first sentence"));
field.highlighterType("unified");
response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get();
assertHighlight(response, 0, "text", 0, 1, equalTo("This is the first sentence"));
// Postings hl also works but the fragment is the whole first sentence (size ignored)
field.highlighterType("postings");
response = client().prepareSearch("test").highlighter(new HighlightBuilder().field(field)).get();
assertHighlight(response, 0, "text", 0, 1, equalTo("This is the first sentence."));
//if there's a match we only return the values with matches (whole value as number_of_fragments == 0)
MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("text", "third fifth");
field.highlighterType("plain");
response = client().prepareSearch("test").setQuery(queryBuilder).highlighter(new HighlightBuilder().field(field)).get();
assertHighlight(response, 0, "text", 0, 2, equalTo("This is the <em>third</em> sentence. This is the fourth sentence."));
assertHighlight(response, 0, "text", 1, 2, equalTo("This is the <em>fifth</em> sentence"));
field.highlighterType("fvh");
response = client().prepareSearch("test").setQuery(queryBuilder).highlighter(new HighlightBuilder().field(field)).get();
assertHighlight(response, 0, "text", 0, 2, equalTo("This is the <em>third</em> sentence. This is the fourth sentence."));
assertHighlight(response, 0, "text", 1, 2, equalTo("This is the <em>fifth</em> sentence"));
field.highlighterType("postings");
response = client().prepareSearch("test").setQuery(queryBuilder).highlighter(new HighlightBuilder().field(field)).get();
assertHighlight(response, 0, "text", 0, 2, equalTo("This is the <em>third</em> sentence. This is the fourth sentence."));
assertHighlight(response, 0, "text", 1, 2, equalTo("This is the <em>fifth</em> sentence"));
field.highlighterType("unified");
response = client().prepareSearch("test").setQuery(queryBuilder).highlighter(new HighlightBuilder().field(field)).get();
assertHighlight(response, 0, "text", 0, 2, equalTo("This is the <em>third</em> sentence. This is the fourth sentence."));
assertHighlight(response, 0, "text", 1, 2, equalTo("This is the <em>fifth</em> sentence"));
}
use of org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder.Field in project elasticsearch by elastic.
the class HighlighterSearchIT method checkMatchedFieldsCase.
private void checkMatchedFieldsCase(boolean requireFieldMatch) throws Exception {
assertAcked(prepareCreate("test").addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties").startObject("foo").field("type", "text").field("term_vector", "with_positions_offsets").field("store", true).field("analyzer", "english").startObject("fields").startObject("plain").field("type", "text").field("term_vector", "with_positions_offsets").field("analyzer", "standard").endObject().endObject().endObject().startObject("bar").field("type", "text").field("term_vector", "with_positions_offsets").field("store", true).field("analyzer", "english").startObject("fields").startObject("plain").field("type", "text").field("term_vector", "with_positions_offsets").field("analyzer", "standard").endObject().endObject().endObject().endObject().endObject().endObject()));
ensureGreen();
index("test", "type1", "1", "foo", "running with scissors");
index("test", "type1", "2", "foo", "cat cat junk junk junk junk junk junk junk cats junk junk", "bar", "cat cat junk junk junk junk junk junk junk cats junk junk");
index("test", "type1", "3", "foo", "weird", "bar", "result");
refresh();
Field fooField = new Field("foo").numOfFragments(1).order("score").fragmentSize(25).highlighterType("fvh").requireFieldMatch(requireFieldMatch);
SearchRequestBuilder req = client().prepareSearch("test").highlighter(new HighlightBuilder().field(fooField));
// First check highlighting without any matched fields set
SearchResponse resp = req.setQuery(queryStringQuery("running scissors").field("foo")).get();
assertHighlight(resp, 0, "foo", 0, equalTo("<em>running</em> with <em>scissors</em>"));
// And that matching a subfield doesn't automatically highlight it
resp = req.setQuery(queryStringQuery("foo.plain:running scissors").field("foo")).get();
assertHighlight(resp, 0, "foo", 0, equalTo("running with <em>scissors</em>"));
// Add the subfield to the list of matched fields but don't match it. Everything should still work
// like before we added it.
fooField = new Field("foo").numOfFragments(1).order("score").fragmentSize(25).highlighterType("fvh").requireFieldMatch(requireFieldMatch);
fooField.matchedFields("foo", "foo.plain");
req = client().prepareSearch("test").highlighter(new HighlightBuilder().field(fooField));
resp = req.setQuery(queryStringQuery("running scissors").field("foo")).get();
assertHighlight(resp, 0, "foo", 0, equalTo("<em>running</em> with <em>scissors</em>"));
// Now make half the matches come from the stored field and half from just a matched field.
resp = req.setQuery(queryStringQuery("foo.plain:running scissors").field("foo")).get();
assertHighlight(resp, 0, "foo", 0, equalTo("<em>running</em> with <em>scissors</em>"));
// Now remove the stored field from the matched field list. That should work too.
fooField = new Field("foo").numOfFragments(1).order("score").fragmentSize(25).highlighterType("fvh").requireFieldMatch(requireFieldMatch);
fooField.matchedFields("foo.plain");
req = client().prepareSearch("test").highlighter(new HighlightBuilder().field(fooField));
resp = req.setQuery(queryStringQuery("foo.plain:running scissors").field("foo")).get();
assertHighlight(resp, 0, "foo", 0, equalTo("<em>running</em> with scissors"));
// Now make sure boosted fields don't blow up when matched fields is both the subfield and stored field.
fooField = new Field("foo").numOfFragments(1).order("score").fragmentSize(25).highlighterType("fvh").requireFieldMatch(requireFieldMatch);
fooField.matchedFields("foo", "foo.plain");
req = client().prepareSearch("test").highlighter(new HighlightBuilder().field(fooField));
resp = req.setQuery(queryStringQuery("foo.plain:running^5 scissors").field("foo")).get();
assertHighlight(resp, 0, "foo", 0, equalTo("<em>running</em> with <em>scissors</em>"));
// Now just all matches are against the matched field. This still returns highlighting.
resp = req.setQuery(queryStringQuery("foo.plain:running foo.plain:scissors").field("foo")).get();
assertHighlight(resp, 0, "foo", 0, equalTo("<em>running</em> with <em>scissors</em>"));
// And all matched field via the queryString's field parameter, just in case
resp = req.setQuery(queryStringQuery("running scissors").field("foo.plain")).get();
assertHighlight(resp, 0, "foo", 0, equalTo("<em>running</em> with <em>scissors</em>"));
// Finding the same string two ways is ok too
resp = req.setQuery(queryStringQuery("run foo.plain:running^5 scissors").field("foo")).get();
assertHighlight(resp, 0, "foo", 0, equalTo("<em>running</em> with <em>scissors</em>"));
// But we use the best found score when sorting fragments
resp = req.setQuery(queryStringQuery("cats foo.plain:cats^5").field("foo")).get();
assertHighlight(resp, 0, "foo", 0, equalTo("junk junk <em>cats</em> junk junk"));
// which can also be written by searching on the subfield
resp = req.setQuery(queryStringQuery("cats").field("foo").field("foo.plain", 5)).get();
assertHighlight(resp, 0, "foo", 0, equalTo("junk junk <em>cats</em> junk junk"));
// Speaking of two fields, you can have two fields, only one of which has matchedFields enabled
QueryBuilder twoFieldsQuery = queryStringQuery("cats").field("foo").field("foo.plain", 5).field("bar").field("bar.plain", 5);
Field barField = new Field("bar").numOfFragments(1).order("score").fragmentSize(25).highlighterType("fvh").requireFieldMatch(requireFieldMatch);
resp = req.setQuery(twoFieldsQuery).highlighter(new HighlightBuilder().field(fooField).field(barField)).get();
assertHighlight(resp, 0, "foo", 0, equalTo("junk junk <em>cats</em> junk junk"));
assertHighlight(resp, 0, "bar", 0, equalTo("<em>cat</em> <em>cat</em> junk junk junk junk"));
// And you can enable matchedField highlighting on both
barField.matchedFields("bar", "bar.plain");
resp = req.setQuery(twoFieldsQuery).highlighter(new HighlightBuilder().field(fooField).field(barField)).get();
assertHighlight(resp, 0, "foo", 0, equalTo("junk junk <em>cats</em> junk junk"));
assertHighlight(resp, 0, "bar", 0, equalTo("junk junk <em>cats</em> junk junk"));
// Setting a matchedField that isn't searched/doesn't exist is simply ignored.
barField.matchedFields("bar", "candy");
resp = req.setQuery(twoFieldsQuery).highlighter(new HighlightBuilder().field(fooField).field(barField)).get();
assertHighlight(resp, 0, "foo", 0, equalTo("junk junk <em>cats</em> junk junk"));
assertHighlight(resp, 0, "bar", 0, equalTo("<em>cat</em> <em>cat</em> junk junk junk junk"));
// If the stored field doesn't have a value it doesn't matter what you match, you get nothing.
barField.matchedFields("bar", "foo.plain");
resp = req.setQuery(queryStringQuery("running scissors").field("foo.plain").field("bar")).highlighter(new HighlightBuilder().field(fooField).field(barField)).get();
assertHighlight(resp, 0, "foo", 0, equalTo("<em>running</em> with <em>scissors</em>"));
assertThat(resp.getHits().getAt(0).getHighlightFields(), not(hasKey("bar")));
// If the stored field is found but the matched field isn't then you don't get a result either.
fooField.matchedFields("bar.plain");
resp = req.setQuery(queryStringQuery("running scissors").field("foo").field("foo.plain").field("bar").field("bar.plain")).highlighter(new HighlightBuilder().field(fooField).field(barField)).get();
assertThat(resp.getHits().getAt(0).getHighlightFields(), not(hasKey("foo")));
// But if you add the stored field to the list of matched fields then you'll get a result again
fooField.matchedFields("foo", "bar.plain");
resp = req.setQuery(queryStringQuery("running scissors").field("foo").field("foo.plain").field("bar").field("bar.plain")).highlighter(new HighlightBuilder().field(fooField).field(barField)).get();
assertHighlight(resp, 0, "foo", 0, equalTo("<em>running</em> with <em>scissors</em>"));
assertThat(resp.getHits().getAt(0).getHighlightFields(), not(hasKey("bar")));
// You _can_ highlight fields that aren't subfields of one another.
resp = req.setQuery(queryStringQuery("weird").field("foo").field("foo.plain").field("bar").field("bar.plain")).highlighter(new HighlightBuilder().field(fooField).field(barField)).get();
assertHighlight(resp, 0, "foo", 0, equalTo("<em>weird</em>"));
assertHighlight(resp, 0, "bar", 0, equalTo("<em>resul</em>t"));
assertFailures(req.setQuery(queryStringQuery("result").field("foo").field("foo.plain").field("bar").field("bar.plain")), RestStatus.INTERNAL_SERVER_ERROR, containsString("IndexOutOfBoundsException"));
}
use of org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder.Field in project elasticsearch by elastic.
the class HighlighterSearchIT method testFastVectorHighlighter.
public void testFastVectorHighlighter() throws Exception {
assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping()));
ensureGreen();
indexRandom(true, client().prepareIndex("test", "type1").setSource("field1", "this is a test", "field2", "The quick brown fox jumps over the lazy dog"));
logger.info("--> highlighting and searching on field1");
SearchSourceBuilder source = searchSource().query(termQuery("field1", "test")).highlighter(highlight().field("field1", 100, 0).order("score").preTags("<xxx>").postTags("</xxx>"));
SearchResponse searchResponse = client().prepareSearch("test").setSource(source).get();
assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("this is a <xxx>test</xxx>"));
logger.info("--> searching with boundary characters");
source = searchSource().query(matchQuery("field2", "quick")).highlighter(highlight().field("field2", 30, 1).boundaryChars(new char[] { ' ' }));
searchResponse = client().prepareSearch("test").setSource(source).get();
assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The <em>quick</em> brown fox jumps over"));
logger.info("--> searching with boundary characters on the field");
source = searchSource().query(matchQuery("field2", "quick")).highlighter(highlight().field(new Field("field2").fragmentSize(30).numOfFragments(1).boundaryChars(new char[] { ' ' })));
searchResponse = client().prepareSearch("test").setSource(source).get();
assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The <em>quick</em> brown fox jumps over"));
}
use of org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder.Field in project elasticsearch by elastic.
the class HighlightBuilderTests method testBuildSearchContextHighlight.
/**
* test that build() outputs a {@link SearchContextHighlight} that is has similar parameters
* than what we have in the random {@link HighlightBuilder}
*/
public void testBuildSearchContextHighlight() throws IOException {
Settings indexSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build();
Index index = new Index(randomAsciiOfLengthBetween(1, 10), "_na_");
IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(index, indexSettings);
// shard context will only need indicesQueriesRegistry for building Query objects nested in highlighter
QueryShardContext mockShardContext = new QueryShardContext(0, idxSettings, null, null, null, null, null, xContentRegistry(), null, null, System::currentTimeMillis) {
@Override
public MappedFieldType fieldMapper(String name) {
TextFieldMapper.Builder builder = new TextFieldMapper.Builder(name);
return builder.build(new Mapper.BuilderContext(idxSettings.getSettings(), new ContentPath(1))).fieldType();
}
};
mockShardContext.setMapUnmappedFieldAsString(true);
for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
HighlightBuilder highlightBuilder = randomHighlighterBuilder();
SearchContextHighlight highlight = highlightBuilder.build(mockShardContext);
for (SearchContextHighlight.Field field : highlight.fields()) {
String encoder = highlightBuilder.encoder() != null ? highlightBuilder.encoder() : HighlightBuilder.DEFAULT_ENCODER;
assertEquals(encoder, field.fieldOptions().encoder());
final Field fieldBuilder = getFieldBuilderByName(highlightBuilder, field.field());
assertNotNull("expected a highlight builder for field " + field.field(), fieldBuilder);
FieldOptions fieldOptions = field.fieldOptions();
BiConsumer<Function<AbstractHighlighterBuilder<?>, Object>, Function<FieldOptions, Object>> checkSame = mergeBeforeChek(highlightBuilder, fieldBuilder, fieldOptions);
checkSame.accept(AbstractHighlighterBuilder::boundaryChars, FieldOptions::boundaryChars);
checkSame.accept(AbstractHighlighterBuilder::boundaryScannerType, FieldOptions::boundaryScannerType);
checkSame.accept(AbstractHighlighterBuilder::boundaryMaxScan, FieldOptions::boundaryMaxScan);
checkSame.accept(AbstractHighlighterBuilder::fragmentSize, FieldOptions::fragmentCharSize);
checkSame.accept(AbstractHighlighterBuilder::fragmenter, FieldOptions::fragmenter);
checkSame.accept(AbstractHighlighterBuilder::requireFieldMatch, FieldOptions::requireFieldMatch);
checkSame.accept(AbstractHighlighterBuilder::noMatchSize, FieldOptions::noMatchSize);
checkSame.accept(AbstractHighlighterBuilder::numOfFragments, FieldOptions::numberOfFragments);
checkSame.accept(AbstractHighlighterBuilder::phraseLimit, FieldOptions::phraseLimit);
checkSame.accept(AbstractHighlighterBuilder::highlighterType, FieldOptions::highlighterType);
checkSame.accept(AbstractHighlighterBuilder::highlightFilter, FieldOptions::highlightFilter);
checkSame.accept(AbstractHighlighterBuilder::preTags, FieldOptions::preTags);
checkSame.accept(AbstractHighlighterBuilder::postTags, FieldOptions::postTags);
checkSame.accept(AbstractHighlighterBuilder::options, FieldOptions::options);
checkSame.accept(AbstractHighlighterBuilder::order, op -> op.scoreOrdered() ? Order.SCORE : Order.NONE);
assertEquals(fieldBuilder.fragmentOffset, fieldOptions.fragmentOffset());
if (fieldBuilder.matchedFields != null) {
String[] copy = Arrays.copyOf(fieldBuilder.matchedFields, fieldBuilder.matchedFields.length);
Arrays.sort(copy);
assertArrayEquals(copy, new TreeSet<>(fieldOptions.matchedFields()).toArray(new String[fieldOptions.matchedFields().size()]));
} else {
assertNull(fieldOptions.matchedFields());
}
Query expectedValue = null;
if (fieldBuilder.highlightQuery != null) {
expectedValue = QueryBuilder.rewriteQuery(fieldBuilder.highlightQuery, mockShardContext).toQuery(mockShardContext);
} else if (highlightBuilder.highlightQuery != null) {
expectedValue = QueryBuilder.rewriteQuery(highlightBuilder.highlightQuery, mockShardContext).toQuery(mockShardContext);
}
assertEquals(expectedValue, fieldOptions.highlightQuery());
}
}
}
Aggregations