From a843008b17efffc4ca897ebf3c0c2db96daa1b7f Mon Sep 17 00:00:00 2001 From: javanna Date: Fri, 8 May 2015 20:12:55 +0200 Subject: [PATCH] Highlighting: require_field_match set to true by default The default `false` for `require_field_match` is a bit odd and confusing for users, given that field names get ignored by default and every field gets highlighted if it contains terms extracted out of the query, regardless of which fields were queries. Changed the default to `true`, it can always be changed per request. Closes #10627 Closes #11067 --- docs/reference/migration/migrate_2_0.asciidoc | 10 ++++++ .../search/request/highlighting.asciidoc | 8 ++--- .../highlight/HighlighterParseElement.java | 2 +- .../highlight/HighlighterSearchTests.java | 32 +++++++++---------- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/docs/reference/migration/migrate_2_0.asciidoc b/docs/reference/migration/migrate_2_0.asciidoc index c91e6e0a74f..53cacf7be16 100644 --- a/docs/reference/migration/migrate_2_0.asciidoc +++ b/docs/reference/migration/migrate_2_0.asciidoc @@ -591,8 +591,18 @@ from fielddata. [float] === Highlighting +The default value for the `require_field_match` option is `true` rather than +`false`, meaning that the highlighters will take the fields that were queried +into account by default. That means for instance that highlighting any field +when querying the `_all` field will produce no highlighted snippets by default, +given that the match was on the `_all` field only. Querying the same fields +that need to be highlighted is the cleaner solution to get highlighted snippets +back. Otherwise `require_field_match` option can be set to `false` to ignore +field names completely when highlighting. + The postings highlighter doesn't support the `require_field_match` option anymore, it will only highlight fields that were queried. The `match` query with type set to `match_phrase_prefix` is not supported by the postings highlighter. No highlighted snippets will be returned. + diff --git a/docs/reference/search/request/highlighting.asciidoc b/docs/reference/search/request/highlighting.asciidoc index 7c43fdc37db..0b5d41e683e 100644 --- a/docs/reference/search/request/highlighting.asciidoc +++ b/docs/reference/search/request/highlighting.asciidoc @@ -404,10 +404,10 @@ at the field level. [[field-match]] ==== Require Field Match -`require_field_match` can be set to `true` which will cause a field to -be highlighted only if a query matched that field. `false` means that -terms are highlighted on all requested fields regardless if the query -matches specifically on them. +`require_field_match` can be set to `false` which will cause any field to +be highlighted regardless of whether the query matched specifically on them. +The default behaviour is `true`, meaning that only fields that hold a query +match will be highlighted. [[boundary-characters]] ==== Boundary Characters diff --git a/src/main/java/org/elasticsearch/search/highlight/HighlighterParseElement.java b/src/main/java/org/elasticsearch/search/highlight/HighlighterParseElement.java index 3613327c679..802122f648d 100644 --- a/src/main/java/org/elasticsearch/search/highlight/HighlighterParseElement.java +++ b/src/main/java/org/elasticsearch/search/highlight/HighlighterParseElement.java @@ -82,7 +82,7 @@ public class HighlighterParseElement implements SearchParseElement { final SearchContextHighlight.FieldOptions.Builder globalOptionsBuilder = new SearchContextHighlight.FieldOptions.Builder() .preTags(DEFAULT_PRE_TAGS).postTags(DEFAULT_POST_TAGS).scoreOrdered(false).highlightFilter(false) - .requireFieldMatch(false).forceSource(false).fragmentCharSize(100).numberOfFragments(5) + .requireFieldMatch(true).forceSource(false).fragmentCharSize(100).numberOfFragments(5) .encoder("default").boundaryMaxScan(SimpleBoundaryScanner.DEFAULT_MAX_SCAN) .boundaryChars(SimpleBoundaryScanner.DEFAULT_BOUNDARY_CHARS) .noMatchSize(0).phraseLimit(256); diff --git a/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchTests.java b/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchTests.java index 89c0b2dc4a7..bc4f78bc50b 100644 --- a/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchTests.java +++ b/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchTests.java @@ -458,7 +458,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { SearchResponse search = client().prepareSearch() .setQuery(matchQuery("title", "bug")) .addHighlightedField("title", -1, 2) - .addHighlightedField("titleTV", -1, 2) + .addHighlightedField("titleTV", -1, 2).setHighlighterRequireFieldMatch(false) .get(); assertHighlight(search, 0, "title", 0, equalTo("This is a test on the highlighting bug present in elasticsearch")); @@ -490,7 +490,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { .query(termQuery("field1", "test")) .highlight(highlight().order("score").preTags("").postTags("").fragmentSize(1).numOfFragments(1) .field(new HighlightBuilder.Field("field1").numOfFragments(2)) - .field(new HighlightBuilder.Field("field2").preTags("").postTags("").fragmentSize(50))); + .field(new HighlightBuilder.Field("field2").preTags("").postTags("").fragmentSize(50).requireFieldMatch(false))); SearchResponse searchResponse = client().prepareSearch("test").setSource(source.buildAsBytes()).get(); @@ -603,7 +603,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { logger.info("--> searching on _all, highlighting on field1"); source = searchSource() .query(termQuery("_all", "test")) - .highlight(highlight().field("field1").order("score").preTags("").postTags("")); + .highlight(highlight().field("field1").order("score").preTags("").postTags("").requireFieldMatch(false)); searchResponse = client().prepareSearch("test").setSource(source.buildAsBytes()).get(); @@ -612,7 +612,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { logger.info("--> searching on _all, highlighting on field2"); source = searchSource() .query(termQuery("_all", "quick")) - .highlight(highlight().field("field2").order("score").preTags("").postTags("")); + .highlight(highlight().field("field2").order("score").preTags("").postTags("").requireFieldMatch(false)); searchResponse = client().prepareSearch("test").setSource(source.buildAsBytes()).get(); @@ -621,7 +621,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { logger.info("--> searching on _all, highlighting on field2"); source = searchSource() .query(prefixQuery("_all", "qui")) - .highlight(highlight().field("field2").order("score").preTags("").postTags("")); + .highlight(highlight().field("field2").order("score").preTags("").postTags("").requireFieldMatch(false)); searchResponse = client().prepareSearch("test").setSource(source.buildAsBytes()).get(); @@ -630,7 +630,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { logger.info("--> searching on _all with constant score, highlighting on field2"); source = searchSource() .query(constantScoreQuery(prefixQuery("_all", "qui"))) - .highlight(highlight().field("field2").order("score").preTags("").postTags("")); + .highlight(highlight().field("field2").order("score").preTags("").postTags("").requireFieldMatch(false)); searchResponse = client().prepareSearch("test").setSource(source.buildAsBytes()).get(); @@ -639,7 +639,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { logger.info("--> searching on _all with constant score, highlighting on field2"); source = searchSource() .query(boolQuery().should(constantScoreQuery(prefixQuery("_all", "qui")))) - .highlight(highlight().field("field2").order("score").preTags("").postTags("")); + .highlight(highlight().field("field2").order("score").preTags("").postTags("").requireFieldMatch(false)); searchResponse = client().prepareSearch("test").setSource(source.buildAsBytes()).get(); assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy dog")); @@ -666,7 +666,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { logger.info("--> searching on _all, highlighting on field1"); source = searchSource() .query(termQuery("_all", "test")) - .highlight(highlight().field("field1", 100, 0).order("score").preTags("").postTags("")); + .highlight(highlight().field("field1", 100, 0).order("score").preTags("").postTags("").requireFieldMatch(false)); searchResponse = client().prepareSearch("test").setSource(source.buildAsBytes()).get(); @@ -676,7 +676,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { logger.info("--> searching on _all, highlighting on field2"); source = searchSource() .query(termQuery("_all", "quick")) - .highlight(highlight().field("field2", 100, 0).order("score").preTags("").postTags("")); + .highlight(highlight().field("field2", 100, 0).order("score").preTags("").postTags("").requireFieldMatch(false)); searchResponse = client().prepareSearch("test").setSource(source.buildAsBytes()).get(); @@ -686,7 +686,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { logger.info("--> searching on _all, highlighting on field2"); source = searchSource() .query(prefixQuery("_all", "qui")) - .highlight(highlight().field("field2", 100, 0).order("score").preTags("").postTags("")); + .highlight(highlight().field("field2", 100, 0).order("score").preTags("").postTags("").requireFieldMatch(false)); searchResponse = client().prepareSearch("test").setSource(source.buildAsBytes()).get(); @@ -1877,7 +1877,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("this is a test")); - logger.info("--> searching on _all, highlighting on field1"); + logger.info("--> searching on field1, highlighting on field1"); source = searchSource() .query(termQuery("field1", "test")) .highlight(highlight().field("field1").preTags("").postTags("")); @@ -1886,7 +1886,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { assertHighlight(searchResponse, 0, "field1", 0, 1, equalTo("this is a test")); - logger.info("--> searching on _all, highlighting on field2"); + logger.info("--> searching on field2, highlighting on field2"); source = searchSource() .query(termQuery("field2", "quick")) .highlight(highlight().field("field2").order("score").preTags("").postTags("")); @@ -1895,7 +1895,7 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy quick dog")); - logger.info("--> searching on _all, highlighting on field2"); + logger.info("--> searching on field2, highlighting on field2"); source = searchSource() .query(matchPhraseQuery("field2", "quick brown")) .highlight(highlight().field("field2").preTags("").postTags("")); @@ -1906,10 +1906,10 @@ public class HighlighterSearchTests extends ElasticsearchIntegrationTest { assertHighlight(searchResponse, 0, "field2", 0, 1, equalTo("The quick brown fox jumps over the lazy quick dog")); //lets fall back to the standard highlighter then, what people would do to highlight query matches - logger.info("--> searching on _all, highlighting on field2, falling back to the plain highlighter"); + logger.info("--> searching on field2, highlighting on field2, falling back to the plain highlighter"); source = searchSource() - .query(matchPhraseQuery("field2", "quick brown")) - .highlight(highlight().field("field2").preTags("").postTags("").highlighterType("highlighter")); + .query(matchPhraseQuery("_all", "quick brown")) + .highlight(highlight().field("field2").preTags("").postTags("").highlighterType("highlighter").requireFieldMatch(false)); searchResponse = client().search(searchRequest("test").source(source)).actionGet();