From 757de805d345cc6f86dfb9212304adca165295a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BCscher?= Date: Thu, 28 Jul 2016 11:57:17 +0200 Subject: [PATCH] `multi_match` query should produce MatchNoDocs query on unknown fieldname Currently when the `fields` parameter used in a `multi_match` query contains a wildcard expression that doesn't resolve to any field name in the target index, MultiMatchQueryBuilder produces a `null` query. This change changes it to be a MatchNoDocs query, since returning no documents for this case is already the current behaviour. Also adding missing field names (with and without wildcards) to the unit and integration test. --- .../index/query/MultiMatchQueryBuilder.java | 7 ++++++- .../org/elasticsearch/index/search/MatchQuery.java | 1 - .../index/query/MultiMatchQueryBuilderTests.java | 13 ++++++++++++- .../search/query/MultiMatchQueryIT.java | 6 +++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java index e2d34db0b4a..41b6829994e 100644 --- a/core/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/MultiMatchQueryBuilder.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.common.lucene.search.MatchNoDocsQuery; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.unit.Fuzziness; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -747,7 +748,11 @@ public class MultiMatchQueryBuilder extends AbstractQueryBuilder { + private static final String MISSING_WILDCARD_FIELD_NAME = "missing_*"; + private static final String MISSING_FIELD_NAME = "missing"; + @Override protected MultiMatchQueryBuilder doCreateTestQueryBuilder() { - String fieldName = randomFrom(STRING_FIELD_NAME, INT_FIELD_NAME, DOUBLE_FIELD_NAME, BOOLEAN_FIELD_NAME, DATE_FIELD_NAME); + String fieldName = randomFrom(STRING_FIELD_NAME, INT_FIELD_NAME, DOUBLE_FIELD_NAME, BOOLEAN_FIELD_NAME, DATE_FIELD_NAME, + MISSING_FIELD_NAME, MISSING_WILDCARD_FIELD_NAME); if (fieldName.equals(DATE_FIELD_NAME)) { assumeTrue("test with date fields runs only when at least a type is registered", getCurrentTypes().length > 0); } + // creates the query with random value and field name Object value; if (fieldName.equals(STRING_FIELD_NAME)) { @@ -238,6 +243,12 @@ public class MultiMatchQueryBuilderTests extends AbstractQueryTestCase 0); + assertThat(multiMatchQuery("test").field(MISSING_WILDCARD_FIELD_NAME).toQuery(createShardContext()), instanceOf(MatchNoDocsQuery.class)); + assertThat(multiMatchQuery("test").field(MISSING_FIELD_NAME).toQuery(createShardContext()), instanceOf(TermQuery.class)); + } + public void testFromJson() throws IOException { String json = "{\n" + diff --git a/core/src/test/java/org/elasticsearch/search/query/MultiMatchQueryIT.java b/core/src/test/java/org/elasticsearch/search/query/MultiMatchQueryIT.java index 766aff8d274..cb55f88ff80 100644 --- a/core/src/test/java/org/elasticsearch/search/query/MultiMatchQueryIT.java +++ b/core/src/test/java/org/elasticsearch/search/query/MultiMatchQueryIT.java @@ -237,7 +237,8 @@ public class MultiMatchQueryIT extends ESIntegTestCase { assertNoFailures(searchResponse); assertFirstHit(searchResponse, hasId("theone")); - String[] fields = {"full_name", "first_name", "last_name", "last_name_phrase", "first_name_phrase", "category_phrase", "category"}; + String[] fields = { "full_name", "first_name", "last_name", "last_name_phrase", "first_name_phrase", "category_phrase", "category", + "missing_field", "missing_fields*" }; String[] query = {"marvel","hero", "captain", "america", "15", "17", "1", "5", "ultimate", "Man", "marvel", "wolferine", "ninja"}; @@ -269,6 +270,9 @@ public class MultiMatchQueryIT extends ESIntegTestCase { .setQuery(matchQueryBuilder).get(); assertThat("field: " + field + " query: " + builder.toString(), multiMatchResp.getHits().getTotalHits(), equalTo(matchResp.getHits().getTotalHits())); SearchHits hits = multiMatchResp.getHits(); + if (field.startsWith("missing")) { + assertEquals(0, hits.hits().length); + } for (int j = 0; j < hits.hits().length; j++) { assertThat(hits.getHits()[j].score(), equalTo(matchResp.getHits().getHits()[j].score())); assertThat(hits.getHits()[j].getId(), equalTo(matchResp.getHits().getHits()[j].getId()));