diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/IndexQueryParserModule.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/IndexQueryParserModule.java index d3a5bb2d5a9..9b58f472955 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/IndexQueryParserModule.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/IndexQueryParserModule.java @@ -227,6 +227,7 @@ public class IndexQueryParserModule extends AbstractModule { bindings.processXContentQueryParser(QueryStringQueryParser.NAME, QueryStringQueryParser.class); bindings.processXContentQueryParser(BoolQueryParser.NAME, BoolQueryParser.class); bindings.processXContentQueryParser(TermQueryParser.NAME, TermQueryParser.class); + bindings.processXContentQueryParser(TermsQueryParser.NAME, TermsQueryParser.class); bindings.processXContentQueryParser(FuzzyQueryParser.NAME, FuzzyQueryParser.class); bindings.processXContentQueryParser(FieldQueryParser.NAME, FieldQueryParser.class); bindings.processXContentQueryParser(RangeQueryParser.NAME, RangeQueryParser.class); diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/FilterBuilders.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/FilterBuilders.java index 95b71b762b7..58010fcd0dc 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/FilterBuilders.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/FilterBuilders.java @@ -153,6 +153,66 @@ public abstract class FilterBuilders { return new TermsFilterBuilder(name, values); } + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsFilterBuilder inFilter(String name, String... values) { + return new TermsFilterBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsFilterBuilder inFilter(String name, int... values) { + return new TermsFilterBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsFilterBuilder inFilter(String name, long... values) { + return new TermsFilterBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsFilterBuilder inFilter(String name, float... values) { + return new TermsFilterBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsFilterBuilder inFilter(String name, double... values) { + return new TermsFilterBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsFilterBuilder inFilter(String name, Object... values) { + return new TermsFilterBuilder(name, values); + } + /** * A filter that restricts search results to values that have a matching prefix in a given * field. diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/QueryBuilders.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/QueryBuilders.java index ba968930290..718849f592c 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/QueryBuilders.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/QueryBuilders.java @@ -422,6 +422,137 @@ public abstract class QueryBuilders { return new HasChildQueryBuilder(type, query); } + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder termsQuery(String name, String... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder termsQuery(String name, int... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder termsQuery(String name, long... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder termsQuery(String name, float... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder termsQuery(String name, double... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder termsQuery(String name, Object... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder inQuery(String name, String... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder inQuery(String name, int... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder inQuery(String name, long... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder inQuery(String name, float... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder inQuery(String name, double... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filer for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public static TermsQueryBuilder inQuery(String name, Object... values) { + return new TermsQueryBuilder(name, values); + } + + /** + * A filter that restricts search results to values that have a matching prefix in a given + * field. + * + * @param name The field name + * @param prefix The prefix + */ + public static PrefixFilterBuilder inQuery(String name, String prefix) { + return new PrefixFilterBuilder(name, prefix); + } + private QueryBuilders() { } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/TermsFilterParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/TermsFilterParser.java index 58be4819212..82149bfaa26 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/TermsFilterParser.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/TermsFilterParser.java @@ -49,7 +49,7 @@ public class TermsFilterParser extends AbstractIndexComponent implements XConten } @Override public String[] names() { - return new String[]{NAME}; + return new String[]{NAME, "in"}; } @Override public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException { diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/TermsQueryBuilder.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/TermsQueryBuilder.java new file mode 100644 index 00000000000..1061e4b5956 --- /dev/null +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/TermsQueryBuilder.java @@ -0,0 +1,163 @@ +/* + * Licensed to Elastic Search and Shay Banon under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Elastic Search licenses this + * file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.index.query.xcontent; + +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; + +/** + * @author kimchy (shay.banon) + */ +public class TermsQueryBuilder extends BaseQueryBuilder { + + private final String name; + + private final Object[] values; + + private int minimumMatch = -1; + + private Boolean disableCoord; + + private float boost = -1; + + /** + * A query for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public TermsQueryBuilder(String name, String... values) { + this(name, (Object[]) values); + } + + /** + * A query for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public TermsQueryBuilder(String name, int... values) { + this.name = name; + this.values = new Integer[values.length]; + for (int i = 0; i < values.length; i++) { + this.values[i] = values[i]; + } + } + + /** + * A query for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public TermsQueryBuilder(String name, long... values) { + this.name = name; + this.values = new Long[values.length]; + for (int i = 0; i < values.length; i++) { + this.values[i] = values[i]; + } + } + + /** + * A query for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public TermsQueryBuilder(String name, float... values) { + this.name = name; + this.values = new Float[values.length]; + for (int i = 0; i < values.length; i++) { + this.values[i] = values[i]; + } + } + + /** + * A query for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public TermsQueryBuilder(String name, double... values) { + this.name = name; + this.values = new Double[values.length]; + for (int i = 0; i < values.length; i++) { + this.values[i] = values[i]; + } + } + + /** + * A query for a field based on several terms matching on any of them. + * + * @param name The field name + * @param values The terms + */ + public TermsQueryBuilder(String name, Object... values) { + this.name = name; + this.values = values; + } + + /** + * Sets the minimum number of matches across the provided terms. Defaults to 1. + */ + public TermsQueryBuilder minimumMatch(int minimumMatch) { + this.minimumMatch = minimumMatch; + return this; + } + + /** + * Sets the boost for this query. Documents matching this query will (in addition to the normal + * weightings) have their score multiplied by the boost provided. + */ + public TermsQueryBuilder boost(float boost) { + this.boost = boost; + return this; + } + + /** + * Disables Similarity#coord(int,int) in scoring. Defualts to false. + */ + public TermsQueryBuilder disableCoord(boolean disableCoord) { + this.disableCoord = disableCoord; + return this; + } + + @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(TermsQueryParser.NAME); + builder.startArray(name); + for (Object value : values) { + builder.value(value); + } + builder.endArray(); + + if (minimumMatch != -1) { + builder.field("minimum_match", minimumMatch); + } + if (disableCoord != null) { + builder.field("disable_coord", disableCoord); + } + if (boost != -1) { + builder.field("boost", boost); + } + + builder.endObject(); + } +} diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/TermsQueryParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/TermsQueryParser.java new file mode 100644 index 00000000000..bd3b6b6fd32 --- /dev/null +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/xcontent/TermsQueryParser.java @@ -0,0 +1,123 @@ +/* + * Licensed to Elastic Search and Shay Banon under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Elastic Search licenses this + * file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.index.query.xcontent; + +import org.apache.lucene.index.Term; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TermQuery; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.index.AbstractIndexComponent; +import org.elasticsearch.index.Index; +import org.elasticsearch.index.mapper.FieldMapper; +import org.elasticsearch.index.mapper.MapperService; +import org.elasticsearch.index.query.QueryParsingException; +import org.elasticsearch.index.settings.IndexSettings; + +import java.io.IOException; +import java.util.List; + +import static org.elasticsearch.common.collect.Lists.*; +import static org.elasticsearch.common.lucene.search.Queries.*; +import static org.elasticsearch.index.query.support.QueryParsers.*; + +/** + *
+ * "terms" : { + * "field_name" : [ "value1", "value2" ] + * "minimum_match" : 1 + * } + *+ * + * @author kimchy (shay.banon) + */ +public class TermsQueryParser extends AbstractIndexComponent implements XContentQueryParser { + + public static final String NAME = "terms"; + + @Inject public TermsQueryParser(Index index, @IndexSettings Settings settings) { + super(index, settings); + } + + @Override public String[] names() { + return new String[]{NAME, "in"}; // allow both "in" and "terms" (since its similar to the "terms" filter) + } + + @Override public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException { + XContentParser parser = parseContext.parser(); + + String fieldName = null; + boolean disableCoord = false; + float boost = 1.0f; + int minimumNumberShouldMatch = 1; + List