From 9d615a4f0b9cd908dc730cdf69c175d33efea592 Mon Sep 17 00:00:00 2001 From: kimchy Date: Wed, 25 Aug 2010 18:06:28 +0300 Subject: [PATCH] Query DSL: Improve `or` and `and` filters to accept just array of filters, closes #336. --- .../index/query/xcontent/AndFilterParser.java | 34 ++++++++++++------- .../index/query/xcontent/OrFilterParser.java | 34 ++++++++++++------- .../query/xcontent/QueryParseContext.java | 10 +++--- .../xcontent/SimpleIndexQueryParserTests.java | 26 ++++++++++++++ .../index/query/xcontent/and-filter2.json | 17 ++++++++++ .../index/query/xcontent/or-filter2.json | 17 ++++++++++ 6 files changed, 109 insertions(+), 29 deletions(-) create mode 100644 modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/and-filter2.json create mode 100644 modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/or-filter2.json diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/AndFilterParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/AndFilterParser.java index c971a71774e..4e5509d3829 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/AndFilterParser.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/AndFilterParser.java @@ -57,19 +57,29 @@ public class AndFilterParser extends AbstractIndexComponent implements XContentF boolean cache = true; String currentFieldName = null; - XContentParser.Token token; - while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { - if (token == XContentParser.Token.FIELD_NAME) { - currentFieldName = parser.currentName(); - } else if (token == XContentParser.Token.START_ARRAY) { - if ("filters".equals(currentFieldName)) { - while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { - filters.add(parseContext.parseInnerFilter()); + XContentParser.Token token = parser.currentToken(); + if (token == XContentParser.Token.START_ARRAY) { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + filters.add(parseContext.parseInnerFilter()); + } + } else { + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (token == XContentParser.Token.START_ARRAY) { + if ("filters".equals(currentFieldName)) { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + filters.add(parseContext.parseInnerFilter()); + } + } else { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + filters.add(parseContext.parseInnerFilter()); + } + } + } else if (token.isValue()) { + if ("cache".equals(currentFieldName)) { + cache = parser.booleanValue(); } - } - } else if (token.isValue()) { - if ("cache".equals(currentFieldName)) { - cache = parser.booleanValue(); } } } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/OrFilterParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/OrFilterParser.java index e6b2257a985..22c3b0748ff 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/OrFilterParser.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/OrFilterParser.java @@ -57,19 +57,29 @@ public class OrFilterParser extends AbstractIndexComponent implements XContentFi boolean cache = true; String currentFieldName = null; - XContentParser.Token token; - while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { - if (token == XContentParser.Token.FIELD_NAME) { - currentFieldName = parser.currentName(); - } else if (token == XContentParser.Token.START_ARRAY) { - if ("filters".equals(currentFieldName)) { - while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { - filters.add(parseContext.parseInnerFilter()); + XContentParser.Token token = parser.currentToken(); + if (token == XContentParser.Token.START_ARRAY) { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + filters.add(parseContext.parseInnerFilter()); + } + } else { + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (token == XContentParser.Token.START_ARRAY) { + if ("filters".equals(currentFieldName)) { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + filters.add(parseContext.parseInnerFilter()); + } + } else { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + filters.add(parseContext.parseInnerFilter()); + } + } + } else if (token.isValue()) { + if ("cache".equals(currentFieldName)) { + cache = parser.booleanValue(); } - } - } else if (token.isValue()) { - if ("cache".equals(currentFieldName)) { - cache = parser.booleanValue(); } } } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/QueryParseContext.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/QueryParseContext.java index 05e964ca7a6..4121e278d9d 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/QueryParseContext.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/QueryParseContext.java @@ -118,14 +118,14 @@ public class QueryParseContext { String queryName = parser.currentName(); // move to the next START_OBJECT token = parser.nextToken(); - assert token == XContentParser.Token.START_OBJECT; + assert token == XContentParser.Token.START_OBJECT || token == XContentParser.Token.START_ARRAY; XContentQueryParser queryParser = queryParserRegistry.queryParser(queryName); if (queryParser == null) { throw new QueryParsingException(index, "No query parser registered for [" + queryName + "]"); } Query result = queryParser.parse(this); - if (parser.currentToken() == XContentParser.Token.END_OBJECT) { + if (parser.currentToken() == XContentParser.Token.END_OBJECT || parser.currentToken() == XContentParser.Token.END_ARRAY) { // if we are at END_OBJECT, move to the next one... parser.nextToken(); } @@ -142,16 +142,16 @@ public class QueryParseContext { token = parser.nextToken(); assert token == XContentParser.Token.FIELD_NAME; String queryName = parser.currentName(); - // move to the next START_OBJECT + // move to the next START_OBJECT or START_ARRAY token = parser.nextToken(); - assert token == XContentParser.Token.START_OBJECT; + assert token == XContentParser.Token.START_OBJECT || token == XContentParser.Token.START_ARRAY; XContentFilterParser filterParser = queryParserRegistry.filterParser(queryName); if (filterParser == null) { throw new QueryParsingException(index, "No query parser registered for [" + queryName + "]"); } Filter result = filterParser.parse(this); - if (parser.currentToken() == XContentParser.Token.END_OBJECT) { + if (parser.currentToken() == XContentParser.Token.END_OBJECT || parser.currentToken() == XContentParser.Token.END_ARRAY) { // if we are at END_OBJECT, move to the next one... parser.nextToken(); } diff --git a/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/SimpleIndexQueryParserTests.java b/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/SimpleIndexQueryParserTests.java index 723b3b3ef24..1dd4b197416 100644 --- a/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/SimpleIndexQueryParserTests.java +++ b/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/SimpleIndexQueryParserTests.java @@ -519,6 +519,19 @@ public class SimpleIndexQueryParserTests { assertThat(((TermFilter) andFilter.filters().get(1)).getTerm(), equalTo(new Term("name.first", "shay4"))); } + @Test public void testAndFilteredQuery2() throws IOException { + IndexQueryParser queryParser = newQueryParser(); + String query = copyToStringFromClasspath("/org/elasticsearch/index/query/xcontent/and-filter2.json"); + Query parsedQuery = queryParser.parse(query); + assertThat(parsedQuery, instanceOf(FilteredQuery.class)); + FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; + + AndFilter andFilter = (AndFilter) filteredQuery.getFilter(); + assertThat(andFilter.filters().size(), equalTo(2)); + assertThat(((TermFilter) andFilter.filters().get(0)).getTerm(), equalTo(new Term("name.first", "shay1"))); + assertThat(((TermFilter) andFilter.filters().get(1)).getTerm(), equalTo(new Term("name.first", "shay4"))); + } + @Test public void testOrFilteredQueryBuilder() throws IOException { IndexQueryParser queryParser = newQueryParser(); Query parsedQuery = queryParser.parse(filtered(matchAllQuery(), orFilter(termFilter("name.first", "shay1"), termFilter("name.first", "shay4")))); @@ -544,6 +557,19 @@ public class SimpleIndexQueryParserTests { assertThat(((TermFilter) orFilter.filters().get(1)).getTerm(), equalTo(new Term("name.first", "shay4"))); } + @Test public void testOrFilteredQuery2() throws IOException { + IndexQueryParser queryParser = newQueryParser(); + String query = copyToStringFromClasspath("/org/elasticsearch/index/query/xcontent/or-filter2.json"); + Query parsedQuery = queryParser.parse(query); + assertThat(parsedQuery, instanceOf(FilteredQuery.class)); + FilteredQuery filteredQuery = (FilteredQuery) parsedQuery; + + OrFilter orFilter = (OrFilter) filteredQuery.getFilter(); + assertThat(orFilter.filters().size(), equalTo(2)); + assertThat(((TermFilter) orFilter.filters().get(0)).getTerm(), equalTo(new Term("name.first", "shay1"))); + assertThat(((TermFilter) orFilter.filters().get(1)).getTerm(), equalTo(new Term("name.first", "shay4"))); + } + @Test public void testNotFilteredQueryBuilder() throws IOException { IndexQueryParser queryParser = newQueryParser(); Query parsedQuery = queryParser.parse(filtered(matchAllQuery(), notFilter(termFilter("name.first", "shay1")))); diff --git a/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/and-filter2.json b/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/and-filter2.json new file mode 100644 index 00000000000..21fb2a35fec --- /dev/null +++ b/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/and-filter2.json @@ -0,0 +1,17 @@ +{ + "filtered" : { + "query" : { + "term" : { "name.first" : "shay" } + }, + "filter" : { + "and" : [ + { + "term" : { "name.first" : "shay1" } + }, + { + "term" : { "name.first" : "shay4" } + } + ] + } + } +} \ No newline at end of file diff --git a/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/or-filter2.json b/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/or-filter2.json new file mode 100644 index 00000000000..05356bfdc73 --- /dev/null +++ b/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/or-filter2.json @@ -0,0 +1,17 @@ +{ + "filtered" : { + "query" : { + "term" : { "name.first" : "shay" } + }, + "filter" : { + "or" : [ + { + "term" : { "name.first" : "shay1" } + }, + { + "term" : { "name.first" : "shay4" } + } + ] + } + } +} \ No newline at end of file