Cut over remaining queries to registerQuery

This commit is contained in:
Nik Everett 2016-04-06 16:38:22 -04:00
parent 37cb00a0b5
commit e0cde29a68
43 changed files with 1655 additions and 2365 deletions

View File

@ -102,7 +102,7 @@ public abstract class BaseTermQueryBuilder<QB extends BaseTermQueryBuilder<QB>>
/**
* Constructs a new base term query.
* In case value is assigned to a string, we internally convert it to a {@link BytesRef}
* because in {@link TermQueryBuilder} and {@link SpanTermQueryParser} string values are parsed to {@link BytesRef}
* because in {@link TermQueryBuilder} and {@link SpanTermQueryBuilder} string values are parsed to {@link BytesRef}
* and we want internal representation of query to be equal regardless of whether it was created from XContent or via Java API.
*
* @param fieldName The name of the field

View File

@ -21,9 +21,12 @@ package org.elasticsearch.index.query;
import org.apache.lucene.queries.BoostingQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
@ -43,6 +46,12 @@ import java.util.Objects;
public class BoostingQueryBuilder extends AbstractQueryBuilder<BoostingQueryBuilder> {
public static final String NAME = "boosting";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final BoostingQueryBuilder PROTOTYPE = new BoostingQueryBuilder(EmptyQueryBuilder.PROTOTYPE, EmptyQueryBuilder.PROTOTYPE);
private static final ParseField POSITIVE_FIELD = new ParseField("positive");
private static final ParseField NEGATIVE_FIELD = new ParseField("negative");
private static final ParseField NEGATIVE_BOOST_FIELD = new ParseField("negative_boost");
private final QueryBuilder positiveQuery;
@ -50,7 +59,6 @@ public class BoostingQueryBuilder extends AbstractQueryBuilder<BoostingQueryBuil
private float negativeBoost = -1;
static final BoostingQueryBuilder PROTOTYPE = new BoostingQueryBuilder(EmptyQueryBuilder.PROTOTYPE, EmptyQueryBuilder.PROTOTYPE);
/**
* Create a new {@link BoostingQueryBuilder}
@ -104,15 +112,72 @@ public class BoostingQueryBuilder extends AbstractQueryBuilder<BoostingQueryBuil
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.field(BoostingQueryParser.POSITIVE_FIELD.getPreferredName());
builder.field(POSITIVE_FIELD.getPreferredName());
positiveQuery.toXContent(builder, params);
builder.field(BoostingQueryParser.NEGATIVE_FIELD.getPreferredName());
builder.field(NEGATIVE_FIELD.getPreferredName());
negativeQuery.toXContent(builder, params);
builder.field(BoostingQueryParser.NEGATIVE_BOOST_FIELD.getPreferredName(), negativeBoost);
builder.field(NEGATIVE_BOOST_FIELD.getPreferredName(), negativeBoost);
printBoostAndQueryName(builder);
builder.endObject();
}
public static BoostingQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
QueryBuilder positiveQuery = null;
boolean positiveQueryFound = false;
QueryBuilder negativeQuery = null;
boolean negativeQueryFound = false;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
float negativeBoost = -1;
String queryName = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, POSITIVE_FIELD)) {
positiveQuery = parseContext.parseInnerQueryBuilder();
positiveQueryFound = true;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, NEGATIVE_FIELD)) {
negativeQuery = parseContext.parseInnerQueryBuilder();
negativeQueryFound = true;
} else {
throw new ParsingException(parser.getTokenLocation(), "[boosting] query does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, NEGATIVE_BOOST_FIELD)) {
negativeBoost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else {
throw new ParsingException(parser.getTokenLocation(), "[boosting] query does not support [" + currentFieldName + "]");
}
}
}
if (!positiveQueryFound) {
throw new ParsingException(parser.getTokenLocation(), "[boosting] query requires 'positive' query to be set'");
}
if (!negativeQueryFound) {
throw new ParsingException(parser.getTokenLocation(), "[boosting] query requires 'negative' query to be set'");
}
if (negativeBoost < 0) {
throw new ParsingException(parser.getTokenLocation(),
"[boosting] query requires 'negative_boost' to be set to be a positive value'");
}
BoostingQueryBuilder boostingQuery = new BoostingQueryBuilder(positiveQuery, negativeQuery);
boostingQuery.negativeBoost(negativeBoost);
boostingQuery.boost(boost);
boostingQuery.queryName(queryName);
return boostingQuery;
}
@Override
public String getWriteableName() {
return NAME;

View File

@ -1,100 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for boosting query
*/
public class BoostingQueryParser implements QueryParser<BoostingQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(BoostingQueryBuilder.NAME);
public static final ParseField POSITIVE_FIELD = new ParseField("positive");
public static final ParseField NEGATIVE_FIELD = new ParseField("negative");
public static final ParseField NEGATIVE_BOOST_FIELD = new ParseField("negative_boost");
@Override
public BoostingQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
QueryBuilder positiveQuery = null;
boolean positiveQueryFound = false;
QueryBuilder negativeQuery = null;
boolean negativeQueryFound = false;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
float negativeBoost = -1;
String queryName = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, POSITIVE_FIELD)) {
positiveQuery = parseContext.parseInnerQueryBuilder();
positiveQueryFound = true;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, NEGATIVE_FIELD)) {
negativeQuery = parseContext.parseInnerQueryBuilder();
negativeQueryFound = true;
} else {
throw new ParsingException(parser.getTokenLocation(), "[boosting] query does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, NEGATIVE_BOOST_FIELD)) {
negativeBoost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else {
throw new ParsingException(parser.getTokenLocation(), "[boosting] query does not support [" + currentFieldName + "]");
}
}
}
if (!positiveQueryFound) {
throw new ParsingException(parser.getTokenLocation(), "[boosting] query requires 'positive' query to be set'");
}
if (!negativeQueryFound) {
throw new ParsingException(parser.getTokenLocation(), "[boosting] query requires 'negative' query to be set'");
}
if (negativeBoost < 0) {
throw new ParsingException(parser.getTokenLocation(),
"[boosting] query requires 'negative_boost' to be set to be a positive value'");
}
BoostingQueryBuilder boostingQuery = new BoostingQueryBuilder(positiveQuery, negativeQuery);
boostingQuery.negativeBoost(negativeBoost);
boostingQuery.boost(boost);
boostingQuery.queryName(queryName);
return boostingQuery;
}
@Override
public BoostingQueryBuilder getBuilderPrototype() {
return BoostingQueryBuilder.PROTOTYPE;
}
}

View File

@ -21,9 +21,12 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
@ -35,11 +38,13 @@ import java.util.Objects;
public class ConstantScoreQueryBuilder extends AbstractQueryBuilder<ConstantScoreQueryBuilder> {
public static final String NAME = "constant_score";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final ConstantScoreQueryBuilder PROTOTYPE = new ConstantScoreQueryBuilder(EmptyQueryBuilder.PROTOTYPE);
private static final ParseField INNER_QUERY_FIELD = new ParseField("filter", "query");
private final QueryBuilder filterBuilder;
static final ConstantScoreQueryBuilder PROTOTYPE = new ConstantScoreQueryBuilder(EmptyQueryBuilder.PROTOTYPE);
/**
* A query that wraps another query and simply returns a constant score equal to the
* query boost for every document in the query.
@ -63,12 +68,62 @@ public class ConstantScoreQueryBuilder extends AbstractQueryBuilder<ConstantScor
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.field(ConstantScoreQueryParser.INNER_QUERY_FIELD.getPreferredName());
builder.field(INNER_QUERY_FIELD.getPreferredName());
filterBuilder.toXContent(builder, params);
printBoostAndQueryName(builder);
builder.endObject();
}
public static ConstantScoreQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
QueryBuilder<?> query = null;
boolean queryFound = false;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
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 (parseContext.isDeprecatedSetting(currentFieldName)) {
// skip
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, INNER_QUERY_FIELD)) {
if (queryFound) {
throw new ParsingException(parser.getTokenLocation(), "[" + ConstantScoreQueryBuilder.NAME + "]"
+ " accepts only one 'filter' element.");
}
query = parseContext.parseInnerQueryBuilder();
queryFound = true;
} else {
throw new ParsingException(parser.getTokenLocation(),
"[constant_score] query does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[constant_score] query does not support [" + currentFieldName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "unexpected token [" + token + "]");
}
}
if (!queryFound) {
throw new ParsingException(parser.getTokenLocation(), "[constant_score] requires a 'filter' element");
}
ConstantScoreQueryBuilder constantScoreBuilder = new ConstantScoreQueryBuilder(query);
constantScoreBuilder.boost(boost);
constantScoreBuilder.queryName(queryName);
return constantScoreBuilder;
}
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
Query innerFilter = filterBuilder.toFilter(context);

View File

@ -1,91 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for constant_score query
*/
public class ConstantScoreQueryParser implements QueryParser<ConstantScoreQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(ConstantScoreQueryBuilder.NAME);
public static final ParseField INNER_QUERY_FIELD = new ParseField("filter", "query");
@Override
public ConstantScoreQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
QueryBuilder<?> query = null;
boolean queryFound = false;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
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 (parseContext.isDeprecatedSetting(currentFieldName)) {
// skip
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, INNER_QUERY_FIELD)) {
if (queryFound) {
throw new ParsingException(parser.getTokenLocation(), "[" + ConstantScoreQueryBuilder.NAME + "]"
+ " accepts only one 'filter' element.");
}
query = parseContext.parseInnerQueryBuilder();
queryFound = true;
} else {
throw new ParsingException(parser.getTokenLocation(),
"[constant_score] query does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[constant_score] query does not support [" + currentFieldName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "unexpected token [" + token + "]");
}
}
if (!queryFound) {
throw new ParsingException(parser.getTokenLocation(), "[constant_score] requires a 'filter' element");
}
ConstantScoreQueryBuilder constantScoreBuilder = new ConstantScoreQueryBuilder(query);
constantScoreBuilder.boost(boost);
constantScoreBuilder.queryName(queryName);
return constantScoreBuilder;
}
@Override
public ConstantScoreQueryBuilder getBuilderPrototype() {
return ConstantScoreQueryBuilder.PROTOTYPE;
}
}

View File

@ -22,10 +22,13 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.spans.FieldMaskingSpanQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MappedFieldType;
import java.io.IOException;
@ -35,14 +38,17 @@ public class FieldMaskingSpanQueryBuilder extends AbstractQueryBuilder<FieldMask
implements SpanQueryBuilder<FieldMaskingSpanQueryBuilder>{
public static final String NAME = "field_masking_span";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final FieldMaskingSpanQueryBuilder PROTOTYPE =
new FieldMaskingSpanQueryBuilder(new SpanTermQueryBuilder("field", "text"), "field");
private static final ParseField FIELD_FIELD = new ParseField("field");
private static final ParseField QUERY_FIELD = new ParseField("query");
private final SpanQueryBuilder queryBuilder;
private final String fieldName;
static final FieldMaskingSpanQueryBuilder PROTOTYPE =
new FieldMaskingSpanQueryBuilder(new SpanTermQueryBuilder("field", "text"), "field");
/**
* Constructs a new {@link FieldMaskingSpanQueryBuilder} given an inner {@link SpanQueryBuilder} for
* a given field
@ -77,13 +83,64 @@ public class FieldMaskingSpanQueryBuilder extends AbstractQueryBuilder<FieldMask
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.field(FieldMaskingSpanQueryParser.QUERY_FIELD.getPreferredName());
builder.field(QUERY_FIELD.getPreferredName());
queryBuilder.toXContent(builder, params);
builder.field(FieldMaskingSpanQueryParser.FIELD_FIELD.getPreferredName(), fieldName);
builder.field(FIELD_FIELD.getPreferredName(), fieldName);
printBoostAndQueryName(builder);
builder.endObject();
}
public static FieldMaskingSpanQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
SpanQueryBuilder inner = null;
String field = null;
String queryName = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "[field_masking_span] query must be of type span query");
}
inner = (SpanQueryBuilder) query;
} else {
throw new ParsingException(parser.getTokenLocation(), "[field_masking_span] query does not support ["
+ currentFieldName + "]");
}
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FIELD_FIELD)) {
field = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[field_masking_span] query does not support [" + currentFieldName + "]");
}
}
}
if (inner == null) {
throw new ParsingException(parser.getTokenLocation(), "field_masking_span must have [query] span query clause");
}
if (field == null) {
throw new ParsingException(parser.getTokenLocation(), "field_masking_span must have [field] set for it");
}
FieldMaskingSpanQueryBuilder queryBuilder = new FieldMaskingSpanQueryBuilder(inner, field);
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
return queryBuilder;
}
@Override
protected SpanQuery doToQuery(QueryShardContext context) throws IOException {
String fieldInQuery = fieldName;

View File

@ -1,93 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for field_masking_span query
*/
public class FieldMaskingSpanQueryParser implements QueryParser<FieldMaskingSpanQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(FieldMaskingSpanQueryBuilder.NAME);
public static final ParseField FIELD_FIELD = new ParseField("field");
public static final ParseField QUERY_FIELD = new ParseField("query");
@Override
public FieldMaskingSpanQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
SpanQueryBuilder inner = null;
String field = null;
String queryName = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "[field_masking_span] query must be of type span query");
}
inner = (SpanQueryBuilder) query;
} else {
throw new ParsingException(parser.getTokenLocation(), "[field_masking_span] query does not support ["
+ currentFieldName + "]");
}
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FIELD_FIELD)) {
field = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[field_masking_span] query does not support [" + currentFieldName + "]");
}
}
}
if (inner == null) {
throw new ParsingException(parser.getTokenLocation(), "field_masking_span must have [query] span query clause");
}
if (field == null) {
throw new ParsingException(parser.getTokenLocation(), "field_masking_span must have [field] set for it");
}
FieldMaskingSpanQueryBuilder queryBuilder = new FieldMaskingSpanQueryBuilder(inner, field);
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
return queryBuilder;
}
@Override
public FieldMaskingSpanQueryBuilder getBuilderPrototype() {
return FieldMaskingSpanQueryBuilder.PROTOTYPE;
}
}

View File

@ -23,12 +23,15 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.query.support.QueryParsers;
@ -45,6 +48,8 @@ import java.util.Objects;
public class FuzzyQueryBuilder extends AbstractQueryBuilder<FuzzyQueryBuilder> implements MultiTermQueryBuilder<FuzzyQueryBuilder> {
public static final String NAME = "fuzzy";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final FuzzyQueryBuilder PROTOTYPE = new FuzzyQueryBuilder();
/** Default maximum edit distance. Defaults to AUTO. */
public static final Fuzziness DEFAULT_FUZZINESS = Fuzziness.AUTO;
@ -59,6 +64,13 @@ public class FuzzyQueryBuilder extends AbstractQueryBuilder<FuzzyQueryBuilder> i
* instead of classic Levenshtein algorithm. Defaults to false. */
public static final boolean DEFAULT_TRANSPOSITIONS = false;
private static final ParseField TERM_FIELD = new ParseField("term");
private static final ParseField VALUE_FIELD = new ParseField("value");
private static final ParseField PREFIX_LENGTH_FIELD = new ParseField("prefix_length");
private static final ParseField MAX_EXPANSIONS_FIELD = new ParseField("max_expansions");
private static final ParseField TRANSPOSITIONS_FIELD = new ParseField("transpositions");
private static final ParseField REWRITE_FIELD = new ParseField("rewrite");
private final String fieldName;
private final Object value;
@ -74,8 +86,6 @@ public class FuzzyQueryBuilder extends AbstractQueryBuilder<FuzzyQueryBuilder> i
private String rewrite;
static final FuzzyQueryBuilder PROTOTYPE = new FuzzyQueryBuilder();
/**
* Constructs a new fuzzy query.
*
@ -216,19 +226,89 @@ public class FuzzyQueryBuilder extends AbstractQueryBuilder<FuzzyQueryBuilder> i
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.startObject(fieldName);
builder.field(FuzzyQueryParser.VALUE_FIELD.getPreferredName(), convertToStringIfBytesRef(this.value));
builder.field(VALUE_FIELD.getPreferredName(), convertToStringIfBytesRef(this.value));
fuzziness.toXContent(builder, params);
builder.field(FuzzyQueryParser.PREFIX_LENGTH_FIELD.getPreferredName(), prefixLength);
builder.field(FuzzyQueryParser.MAX_EXPANSIONS_FIELD.getPreferredName(), maxExpansions);
builder.field(FuzzyQueryParser.TRANSPOSITIONS_FIELD.getPreferredName(), transpositions);
builder.field(PREFIX_LENGTH_FIELD.getPreferredName(), prefixLength);
builder.field(MAX_EXPANSIONS_FIELD.getPreferredName(), maxExpansions);
builder.field(TRANSPOSITIONS_FIELD.getPreferredName(), transpositions);
if (rewrite != null) {
builder.field(FuzzyQueryParser.REWRITE_FIELD.getPreferredName(), rewrite);
builder.field(REWRITE_FIELD.getPreferredName(), rewrite);
}
printBoostAndQueryName(builder);
builder.endObject();
builder.endObject();
}
public static FuzzyQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.FIELD_NAME) {
throw new ParsingException(parser.getTokenLocation(), "[fuzzy] query malformed, no field");
}
String fieldName = parser.currentName();
Object value = null;
Fuzziness fuzziness = FuzzyQueryBuilder.DEFAULT_FUZZINESS;
int prefixLength = FuzzyQueryBuilder.DEFAULT_PREFIX_LENGTH;
int maxExpansions = FuzzyQueryBuilder.DEFAULT_MAX_EXPANSIONS;
boolean transpositions = FuzzyQueryBuilder.DEFAULT_TRANSPOSITIONS;
String rewrite = null;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
token = parser.nextToken();
if (token == XContentParser.Token.START_OBJECT) {
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, TERM_FIELD)) {
value = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, VALUE_FIELD)) {
value = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Fuzziness.FIELD)) {
fuzziness = Fuzziness.parse(parser);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, PREFIX_LENGTH_FIELD)) {
prefixLength = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MAX_EXPANSIONS_FIELD)) {
maxExpansions = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TRANSPOSITIONS_FIELD)) {
transpositions = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, REWRITE_FIELD)) {
rewrite = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[fuzzy] query does not support [" + currentFieldName + "]");
}
}
}
parser.nextToken();
} else {
value = parser.objectBytes();
// move to the next token
parser.nextToken();
}
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "no value specified for fuzzy query");
}
return new FuzzyQueryBuilder(fieldName, value)
.fuzziness(fuzziness)
.prefixLength(prefixLength)
.maxExpansions(maxExpansions)
.transpositions(transpositions)
.rewrite(rewrite)
.boost(boost)
.queryName(queryName);
}
@Override
public String getWriteableName() {
return NAME;

View File

@ -1,119 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* @deprecated Fuzzy queries are not useful enough. This class will be removed with Elasticsearch 4.0. In most cases you may want to use
* a match query with the fuzziness parameter for strings or range queries for numeric and date fields.
*/
@Deprecated
public class FuzzyQueryParser implements QueryParser<FuzzyQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(FuzzyQueryBuilder.NAME);
public static final ParseField TERM_FIELD = new ParseField("term");
public static final ParseField VALUE_FIELD = new ParseField("value");
public static final ParseField PREFIX_LENGTH_FIELD = new ParseField("prefix_length");
public static final ParseField MAX_EXPANSIONS_FIELD = new ParseField("max_expansions");
public static final ParseField TRANSPOSITIONS_FIELD = new ParseField("transpositions");
public static final ParseField REWRITE_FIELD = new ParseField("rewrite");
@Override
public FuzzyQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.FIELD_NAME) {
throw new ParsingException(parser.getTokenLocation(), "[fuzzy] query malformed, no field");
}
String fieldName = parser.currentName();
Object value = null;
Fuzziness fuzziness = FuzzyQueryBuilder.DEFAULT_FUZZINESS;
int prefixLength = FuzzyQueryBuilder.DEFAULT_PREFIX_LENGTH;
int maxExpansions = FuzzyQueryBuilder.DEFAULT_MAX_EXPANSIONS;
boolean transpositions = FuzzyQueryBuilder.DEFAULT_TRANSPOSITIONS;
String rewrite = null;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
token = parser.nextToken();
if (token == XContentParser.Token.START_OBJECT) {
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, TERM_FIELD)) {
value = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, VALUE_FIELD)) {
value = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Fuzziness.FIELD)) {
fuzziness = Fuzziness.parse(parser);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, PREFIX_LENGTH_FIELD)) {
prefixLength = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MAX_EXPANSIONS_FIELD)) {
maxExpansions = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TRANSPOSITIONS_FIELD)) {
transpositions = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, REWRITE_FIELD)) {
rewrite = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[fuzzy] query does not support [" + currentFieldName + "]");
}
}
}
parser.nextToken();
} else {
value = parser.objectBytes();
// move to the next token
parser.nextToken();
}
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "no value specified for fuzzy query");
}
return new FuzzyQueryBuilder(fieldName, value)
.fuzziness(fuzziness)
.prefixLength(prefixLength)
.maxExpansions(maxExpansions)
.transpositions(transpositions)
.rewrite(rewrite)
.boost(boost)
.queryName(queryName);
}
@Override
public FuzzyQueryBuilder getBuilderPrototype() {
return FuzzyQueryBuilder.PROTOTYPE;
}
}

View File

@ -20,10 +20,13 @@
package org.elasticsearch.index.query;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
@ -33,8 +36,8 @@ import java.io.IOException;
public class MatchAllQueryBuilder extends AbstractQueryBuilder<MatchAllQueryBuilder> {
public static final String NAME = "match_all";
static final MatchAllQueryBuilder PROTOTYPE = new MatchAllQueryBuilder();
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final MatchAllQueryBuilder PROTOTYPE = new MatchAllQueryBuilder();
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
@ -43,6 +46,36 @@ public class MatchAllQueryBuilder extends AbstractQueryBuilder<MatchAllQueryBuil
builder.endObject();
}
public static MatchAllQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String currentFieldName = null;
XContentParser.Token token;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
while (((token = parser.nextToken()) != XContentParser.Token.END_OBJECT && token != XContentParser.Token.END_ARRAY)) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + MatchAllQueryBuilder.NAME +
"] query does not support [" + currentFieldName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + MatchAllQueryBuilder.NAME +
"] unknown token [" + token + "] after [" + currentFieldName + "]");
}
}
MatchAllQueryBuilder queryBuilder = new MatchAllQueryBuilder();
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
return queryBuilder;
}
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
return Queries.newMatchAllQuery();

View File

@ -1,70 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for match_all query
*/
public class MatchAllQueryParser implements QueryParser<MatchAllQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(MatchAllQueryBuilder.NAME);
@Override
public MatchAllQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String currentFieldName = null;
XContentParser.Token token;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
while (((token = parser.nextToken()) != XContentParser.Token.END_OBJECT && token != XContentParser.Token.END_ARRAY)) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + MatchAllQueryBuilder.NAME +
"] query does not support [" + currentFieldName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + MatchAllQueryBuilder.NAME +
"] unknown token [" + token + "] after [" + currentFieldName + "]");
}
}
MatchAllQueryBuilder queryBuilder = new MatchAllQueryBuilder();
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
return queryBuilder;
}
@Override
public MatchAllQueryBuilder getBuilderPrototype() {
return MatchAllQueryBuilder.PROTOTYPE;
}
}

View File

@ -37,6 +37,7 @@ import org.elasticsearch.client.Client;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.StreamInput;
@ -80,6 +81,8 @@ import static org.elasticsearch.index.mapper.Uid.createUidAsBytes;
public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQueryBuilder> {
public static final String NAME = "more_like_this";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME, "mlt");
public static final MoreLikeThisQueryBuilder PROTOTYPE = new MoreLikeThisQueryBuilder(new String[]{"_na_"}, null);
public static final int DEFAULT_MAX_QUERY_TERMS = XMoreLikeThis.DEFAULT_MAX_QUERY_TERMS;
public static final int DEFAULT_MIN_TERM_FREQ = XMoreLikeThis.DEFAULT_MIN_TERM_FREQ;
@ -92,6 +95,27 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
public static final boolean DEFAULT_INCLUDE = false;
public static final boolean DEFAULT_FAIL_ON_UNSUPPORTED_FIELDS = true;
private interface Field {
ParseField FIELDS = new ParseField("fields");
ParseField LIKE = new ParseField("like");
ParseField UNLIKE = new ParseField("unlike");
ParseField LIKE_TEXT = new ParseField("like_text").withAllDeprecated("like");
ParseField IDS = new ParseField("ids").withAllDeprecated("like");
ParseField DOCS = new ParseField("docs").withAllDeprecated("like");
ParseField MAX_QUERY_TERMS = new ParseField("max_query_terms");
ParseField MIN_TERM_FREQ = new ParseField("min_term_freq");
ParseField MIN_DOC_FREQ = new ParseField("min_doc_freq");
ParseField MAX_DOC_FREQ = new ParseField("max_doc_freq");
ParseField MIN_WORD_LENGTH = new ParseField("min_word_length", "min_word_len");
ParseField MAX_WORD_LENGTH = new ParseField("max_word_length", "max_word_len");
ParseField STOP_WORDS = new ParseField("stop_words");
ParseField ANALYZER = new ParseField("analyzer");
ParseField MINIMUM_SHOULD_MATCH = new ParseField("minimum_should_match");
ParseField BOOST_TERMS = new ParseField("boost_terms");
ParseField INCLUDE = new ParseField("include");
ParseField FAIL_ON_UNSUPPORTED_FIELD = new ParseField("fail_on_unsupported_field");
}
// document inputs
private final String[] fields;
private final String[] likeTexts;
@ -117,8 +141,6 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
// other parameters
private boolean failOnUnsupportedField = DEFAULT_FAIL_ON_UNSUPPORTED_FIELDS;
static final MoreLikeThisQueryBuilder PROTOTYPE = new MoreLikeThisQueryBuilder(new String[]{"_na_"}, null);
/**
* A single item to be used for a {@link MoreLikeThisQueryBuilder}.
*/
@ -711,30 +733,194 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder<MoreLikeThisQ
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
if (fields != null) {
builder.field(MoreLikeThisQueryParser.Field.FIELDS.getPreferredName(), fields);
builder.field(Field.FIELDS.getPreferredName(), fields);
}
buildLikeField(builder, MoreLikeThisQueryParser.Field.LIKE.getPreferredName(), likeTexts, likeItems);
buildLikeField(builder, MoreLikeThisQueryParser.Field.UNLIKE.getPreferredName(), unlikeTexts, unlikeItems);
builder.field(MoreLikeThisQueryParser.Field.MAX_QUERY_TERMS.getPreferredName(), maxQueryTerms);
builder.field(MoreLikeThisQueryParser.Field.MIN_TERM_FREQ.getPreferredName(), minTermFreq);
builder.field(MoreLikeThisQueryParser.Field.MIN_DOC_FREQ.getPreferredName(), minDocFreq);
builder.field(MoreLikeThisQueryParser.Field.MAX_DOC_FREQ.getPreferredName(), maxDocFreq);
builder.field(MoreLikeThisQueryParser.Field.MIN_WORD_LENGTH.getPreferredName(), minWordLength);
builder.field(MoreLikeThisQueryParser.Field.MAX_WORD_LENGTH.getPreferredName(), maxWordLength);
buildLikeField(builder, Field.LIKE.getPreferredName(), likeTexts, likeItems);
buildLikeField(builder, Field.UNLIKE.getPreferredName(), unlikeTexts, unlikeItems);
builder.field(Field.MAX_QUERY_TERMS.getPreferredName(), maxQueryTerms);
builder.field(Field.MIN_TERM_FREQ.getPreferredName(), minTermFreq);
builder.field(Field.MIN_DOC_FREQ.getPreferredName(), minDocFreq);
builder.field(Field.MAX_DOC_FREQ.getPreferredName(), maxDocFreq);
builder.field(Field.MIN_WORD_LENGTH.getPreferredName(), minWordLength);
builder.field(Field.MAX_WORD_LENGTH.getPreferredName(), maxWordLength);
if (stopWords != null) {
builder.field(MoreLikeThisQueryParser.Field.STOP_WORDS.getPreferredName(), stopWords);
builder.field(Field.STOP_WORDS.getPreferredName(), stopWords);
}
if (analyzer != null) {
builder.field(MoreLikeThisQueryParser.Field.ANALYZER.getPreferredName(), analyzer);
builder.field(Field.ANALYZER.getPreferredName(), analyzer);
}
builder.field(MoreLikeThisQueryParser.Field.MINIMUM_SHOULD_MATCH.getPreferredName(), minimumShouldMatch);
builder.field(MoreLikeThisQueryParser.Field.BOOST_TERMS.getPreferredName(), boostTerms);
builder.field(MoreLikeThisQueryParser.Field.INCLUDE.getPreferredName(), include);
builder.field(MoreLikeThisQueryParser.Field.FAIL_ON_UNSUPPORTED_FIELD.getPreferredName(), failOnUnsupportedField);
builder.field(Field.MINIMUM_SHOULD_MATCH.getPreferredName(), minimumShouldMatch);
builder.field(Field.BOOST_TERMS.getPreferredName(), boostTerms);
builder.field(Field.INCLUDE.getPreferredName(), include);
builder.field(Field.FAIL_ON_UNSUPPORTED_FIELD.getPreferredName(), failOnUnsupportedField);
printBoostAndQueryName(builder);
builder.endObject();
}
public static MoreLikeThisQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
// document inputs
List<String> fields = null;
List<String> likeTexts = new ArrayList<>();
List<String> unlikeTexts = new ArrayList<>();
List<Item> likeItems = new ArrayList<>();
List<Item> unlikeItems = new ArrayList<>();
// term selection parameters
int maxQueryTerms = MoreLikeThisQueryBuilder.DEFAULT_MAX_QUERY_TERMS;
int minTermFreq = MoreLikeThisQueryBuilder.DEFAULT_MIN_TERM_FREQ;
int minDocFreq = MoreLikeThisQueryBuilder.DEFAULT_MIN_DOC_FREQ;
int maxDocFreq = MoreLikeThisQueryBuilder.DEFAULT_MAX_DOC_FREQ;
int minWordLength = MoreLikeThisQueryBuilder.DEFAULT_MIN_WORD_LENGTH;
int maxWordLength = MoreLikeThisQueryBuilder.DEFAULT_MAX_WORD_LENGTH;
List<String> stopWords = null;
String analyzer = null;
// query formation parameters
String minimumShouldMatch = MoreLikeThisQueryBuilder.DEFAULT_MINIMUM_SHOULD_MATCH;
float boostTerms = MoreLikeThisQueryBuilder.DEFAULT_BOOST_TERMS;
boolean include = MoreLikeThisQueryBuilder.DEFAULT_INCLUDE;
// other parameters
boolean failOnUnsupportedField = MoreLikeThisQueryBuilder.DEFAULT_FAIL_ON_UNSUPPORTED_FIELDS;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
XContentParser.Token token;
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, Field.LIKE)) {
parseLikeField(parseContext, likeTexts, likeItems);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.UNLIKE)) {
parseLikeField(parseContext, unlikeTexts, unlikeItems);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.LIKE_TEXT)) {
likeTexts.add(parser.text());
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MAX_QUERY_TERMS)) {
maxQueryTerms = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MIN_TERM_FREQ)) {
minTermFreq =parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MIN_DOC_FREQ)) {
minDocFreq = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MAX_DOC_FREQ)) {
maxDocFreq = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MIN_WORD_LENGTH)) {
minWordLength = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MAX_WORD_LENGTH)) {
maxWordLength = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.ANALYZER)) {
analyzer = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MINIMUM_SHOULD_MATCH)) {
minimumShouldMatch = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.BOOST_TERMS)) {
boostTerms = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.INCLUDE)) {
include = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.FAIL_ON_UNSUPPORTED_FIELD)) {
failOnUnsupportedField = parser.booleanValue();
} else if ("boost".equals(currentFieldName)) {
boost = parser.floatValue();
} else if ("_name".equals(currentFieldName)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[mlt] query does not support [" + currentFieldName + "]");
}
} else if (token == XContentParser.Token.START_ARRAY) {
if (parseContext.parseFieldMatcher().match(currentFieldName, Field.FIELDS)) {
fields = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
fields.add(parser.text());
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.LIKE)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
parseLikeField(parseContext, likeTexts, likeItems);
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.UNLIKE)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
parseLikeField(parseContext, unlikeTexts, unlikeItems);
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.IDS)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (!token.isValue()) {
throw new IllegalArgumentException("ids array element should only contain ids");
}
likeItems.add(new Item(null, null, parser.text()));
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.DOCS)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (token != XContentParser.Token.START_OBJECT) {
throw new IllegalArgumentException("docs array element should include an object");
}
likeItems.add(Item.parse(parser, parseContext.parseFieldMatcher(), new Item()));
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.STOP_WORDS)) {
stopWords = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
stopWords.add(parser.text());
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[mlt] query does not support [" + currentFieldName + "]");
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, Field.LIKE)) {
parseLikeField(parseContext, likeTexts, likeItems);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.UNLIKE)) {
parseLikeField(parseContext, unlikeTexts, unlikeItems);
} else {
throw new ParsingException(parser.getTokenLocation(), "[mlt] query does not support [" + currentFieldName + "]");
}
}
}
if (likeTexts.isEmpty() && likeItems.isEmpty()) {
throw new ParsingException(parser.getTokenLocation(), "more_like_this requires 'like' to be specified");
}
if (fields != null && fields.isEmpty()) {
throw new ParsingException(parser.getTokenLocation(), "more_like_this requires 'fields' to be non-empty");
}
String[] fieldsArray = fields == null ? null : fields.toArray(new String[fields.size()]);
String[] likeTextsArray = likeTexts.isEmpty() ? null : likeTexts.toArray(new String[likeTexts.size()]);
String[] unlikeTextsArray = unlikeTexts.isEmpty() ? null : unlikeTexts.toArray(new String[unlikeTexts.size()]);
Item[] likeItemsArray = likeItems.isEmpty() ? null : likeItems.toArray(new Item[likeItems.size()]);
Item[] unlikeItemsArray = unlikeItems.isEmpty() ? null : unlikeItems.toArray(new Item[unlikeItems.size()]);
MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = new MoreLikeThisQueryBuilder(fieldsArray, likeTextsArray, likeItemsArray)
.unlike(unlikeTextsArray)
.unlike(unlikeItemsArray)
.maxQueryTerms(maxQueryTerms)
.minTermFreq(minTermFreq)
.minDocFreq(minDocFreq)
.maxDocFreq(maxDocFreq)
.minWordLength(minWordLength)
.maxWordLength(maxWordLength)
.analyzer(analyzer)
.minimumShouldMatch(minimumShouldMatch)
.boostTerms(boostTerms)
.include(include)
.failOnUnsupportedField(failOnUnsupportedField)
.boost(boost)
.queryName(queryName);
if (stopWords != null) {
moreLikeThisQueryBuilder.stopWords(stopWords);
}
return moreLikeThisQueryBuilder;
}
private static void parseLikeField(QueryParseContext parseContext, List<String> texts, List<Item> items) throws IOException {
XContentParser parser = parseContext.parser();
if (parser.currentToken().isValue()) {
texts.add(parser.text());
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
items.add(Item.parse(parser, parseContext.parseFieldMatcher(), new Item()));
} else {
throw new IllegalArgumentException("Content of 'like' parameter should either be a string or an object");
}
}
private static void buildLikeField(XContentBuilder builder, String fieldName, String[] texts, Item[] items) throws IOException {
if (texts.length > 0 || items.length > 0) {
builder.startArray(fieldName);

View File

@ -1,230 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.MoreLikeThisQueryBuilder.Item;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Parser for the More Like This Query (MLT Query) which finds documents that are "like" a given set of documents.
*
* The documents are provided as a set of strings and/or a list of {@link Item}.
*/
public class MoreLikeThisQueryParser implements QueryParser<MoreLikeThisQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(MoreLikeThisQueryBuilder.NAME, "mlt");
public interface Field {
ParseField FIELDS = new ParseField("fields");
ParseField LIKE = new ParseField("like");
ParseField UNLIKE = new ParseField("unlike");
ParseField LIKE_TEXT = new ParseField("like_text").withAllDeprecated("like");
ParseField IDS = new ParseField("ids").withAllDeprecated("like");
ParseField DOCS = new ParseField("docs").withAllDeprecated("like");
ParseField MAX_QUERY_TERMS = new ParseField("max_query_terms");
ParseField MIN_TERM_FREQ = new ParseField("min_term_freq");
ParseField MIN_DOC_FREQ = new ParseField("min_doc_freq");
ParseField MAX_DOC_FREQ = new ParseField("max_doc_freq");
ParseField MIN_WORD_LENGTH = new ParseField("min_word_length", "min_word_len");
ParseField MAX_WORD_LENGTH = new ParseField("max_word_length", "max_word_len");
ParseField STOP_WORDS = new ParseField("stop_words");
ParseField ANALYZER = new ParseField("analyzer");
ParseField MINIMUM_SHOULD_MATCH = new ParseField("minimum_should_match");
ParseField BOOST_TERMS = new ParseField("boost_terms");
ParseField INCLUDE = new ParseField("include");
ParseField FAIL_ON_UNSUPPORTED_FIELD = new ParseField("fail_on_unsupported_field");
}
@Override
public MoreLikeThisQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
// document inputs
List<String> fields = null;
List<String> likeTexts = new ArrayList<>();
List<String> unlikeTexts = new ArrayList<>();
List<Item> likeItems = new ArrayList<>();
List<Item> unlikeItems = new ArrayList<>();
// term selection parameters
int maxQueryTerms = MoreLikeThisQueryBuilder.DEFAULT_MAX_QUERY_TERMS;
int minTermFreq = MoreLikeThisQueryBuilder.DEFAULT_MIN_TERM_FREQ;
int minDocFreq = MoreLikeThisQueryBuilder.DEFAULT_MIN_DOC_FREQ;
int maxDocFreq = MoreLikeThisQueryBuilder.DEFAULT_MAX_DOC_FREQ;
int minWordLength = MoreLikeThisQueryBuilder.DEFAULT_MIN_WORD_LENGTH;
int maxWordLength = MoreLikeThisQueryBuilder.DEFAULT_MAX_WORD_LENGTH;
List<String> stopWords = null;
String analyzer = null;
// query formation parameters
String minimumShouldMatch = MoreLikeThisQueryBuilder.DEFAULT_MINIMUM_SHOULD_MATCH;
float boostTerms = MoreLikeThisQueryBuilder.DEFAULT_BOOST_TERMS;
boolean include = MoreLikeThisQueryBuilder.DEFAULT_INCLUDE;
// other parameters
boolean failOnUnsupportedField = MoreLikeThisQueryBuilder.DEFAULT_FAIL_ON_UNSUPPORTED_FIELDS;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
XContentParser.Token token;
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, Field.LIKE)) {
parseLikeField(parseContext, likeTexts, likeItems);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.UNLIKE)) {
parseLikeField(parseContext, unlikeTexts, unlikeItems);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.LIKE_TEXT)) {
likeTexts.add(parser.text());
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MAX_QUERY_TERMS)) {
maxQueryTerms = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MIN_TERM_FREQ)) {
minTermFreq =parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MIN_DOC_FREQ)) {
minDocFreq = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MAX_DOC_FREQ)) {
maxDocFreq = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MIN_WORD_LENGTH)) {
minWordLength = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MAX_WORD_LENGTH)) {
maxWordLength = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.ANALYZER)) {
analyzer = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.MINIMUM_SHOULD_MATCH)) {
minimumShouldMatch = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.BOOST_TERMS)) {
boostTerms = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.INCLUDE)) {
include = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.FAIL_ON_UNSUPPORTED_FIELD)) {
failOnUnsupportedField = parser.booleanValue();
} else if ("boost".equals(currentFieldName)) {
boost = parser.floatValue();
} else if ("_name".equals(currentFieldName)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[mlt] query does not support [" + currentFieldName + "]");
}
} else if (token == XContentParser.Token.START_ARRAY) {
if (parseContext.parseFieldMatcher().match(currentFieldName, Field.FIELDS)) {
fields = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
fields.add(parser.text());
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.LIKE)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
parseLikeField(parseContext, likeTexts, likeItems);
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.UNLIKE)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
parseLikeField(parseContext, unlikeTexts, unlikeItems);
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.IDS)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (!token.isValue()) {
throw new IllegalArgumentException("ids array element should only contain ids");
}
likeItems.add(new Item(null, null, parser.text()));
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.DOCS)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (token != XContentParser.Token.START_OBJECT) {
throw new IllegalArgumentException("docs array element should include an object");
}
likeItems.add(Item.parse(parser, parseContext.parseFieldMatcher(), new Item()));
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.STOP_WORDS)) {
stopWords = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
stopWords.add(parser.text());
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[mlt] query does not support [" + currentFieldName + "]");
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, Field.LIKE)) {
parseLikeField(parseContext, likeTexts, likeItems);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Field.UNLIKE)) {
parseLikeField(parseContext, unlikeTexts, unlikeItems);
} else {
throw new ParsingException(parser.getTokenLocation(), "[mlt] query does not support [" + currentFieldName + "]");
}
}
}
if (likeTexts.isEmpty() && likeItems.isEmpty()) {
throw new ParsingException(parser.getTokenLocation(), "more_like_this requires 'like' to be specified");
}
if (fields != null && fields.isEmpty()) {
throw new ParsingException(parser.getTokenLocation(), "more_like_this requires 'fields' to be non-empty");
}
String[] fieldsArray = fields == null ? null : fields.toArray(new String[fields.size()]);
String[] likeTextsArray = likeTexts.isEmpty() ? null : likeTexts.toArray(new String[likeTexts.size()]);
String[] unlikeTextsArray = unlikeTexts.isEmpty() ? null : unlikeTexts.toArray(new String[unlikeTexts.size()]);
Item[] likeItemsArray = likeItems.isEmpty() ? null : likeItems.toArray(new Item[likeItems.size()]);
Item[] unlikeItemsArray = unlikeItems.isEmpty() ? null : unlikeItems.toArray(new Item[unlikeItems.size()]);
MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = new MoreLikeThisQueryBuilder(fieldsArray, likeTextsArray, likeItemsArray)
.unlike(unlikeTextsArray)
.unlike(unlikeItemsArray)
.maxQueryTerms(maxQueryTerms)
.minTermFreq(minTermFreq)
.minDocFreq(minDocFreq)
.maxDocFreq(maxDocFreq)
.minWordLength(minWordLength)
.maxWordLength(maxWordLength)
.analyzer(analyzer)
.minimumShouldMatch(minimumShouldMatch)
.boostTerms(boostTerms)
.include(include)
.failOnUnsupportedField(failOnUnsupportedField)
.boost(boost)
.queryName(queryName);
if (stopWords != null) {
moreLikeThisQueryBuilder.stopWords(stopWords);
}
return moreLikeThisQueryBuilder;
}
private static void parseLikeField(QueryParseContext parseContext, List<String> texts, List<Item> items) throws IOException {
XContentParser parser = parseContext.parser();
if (parser.currentToken().isValue()) {
texts.add(parser.text());
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
items.add(Item.parse(parser, parseContext.parseFieldMatcher(), new Item()));
} else {
throw new IllegalArgumentException("Content of 'like' parameter should either be a string or an object");
}
}
@Override
public MoreLikeThisQueryBuilder getBuilderPrototype() {
return MoreLikeThisQueryBuilder.PROTOTYPE;
}
}

View File

@ -23,11 +23,14 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.query.support.QueryParsers;
@ -40,6 +43,11 @@ import java.util.Objects;
public class PrefixQueryBuilder extends AbstractQueryBuilder<PrefixQueryBuilder> implements MultiTermQueryBuilder<PrefixQueryBuilder> {
public static final String NAME = "prefix";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final PrefixQueryBuilder PROTOTYPE = new PrefixQueryBuilder("field", "value");
private static final ParseField PREFIX_FIELD = new ParseField("value", "prefix");
private static final ParseField REWRITE_FIELD = new ParseField("rewrite");
private final String fieldName;
@ -47,8 +55,6 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder<PrefixQueryBuilder>
private String rewrite;
static final PrefixQueryBuilder PROTOTYPE = new PrefixQueryBuilder("field", "value");
/**
* A Query that matches documents containing terms with a specified prefix.
*
@ -87,15 +93,66 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder<PrefixQueryBuilder>
public void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.startObject(fieldName);
builder.field(PrefixQueryParser.PREFIX_FIELD.getPreferredName(), this.value);
builder.field(PREFIX_FIELD.getPreferredName(), this.value);
if (rewrite != null) {
builder.field(PrefixQueryParser.REWRITE_FIELD.getPreferredName(), rewrite);
builder.field(REWRITE_FIELD.getPreferredName(), rewrite);
}
printBoostAndQueryName(builder);
builder.endObject();
builder.endObject();
}
public static PrefixQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = parser.currentName();
String value = null;
String rewrite = null;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
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 (parseContext.isDeprecatedSetting(currentFieldName)) {
// skip
} else if (token == XContentParser.Token.START_OBJECT) {
fieldName = currentFieldName;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, PREFIX_FIELD)) {
value = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, REWRITE_FIELD)) {
rewrite = parser.textOrNull();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[regexp] query does not support [" + currentFieldName + "]");
}
}
}
} else {
fieldName = currentFieldName;
value = parser.textOrNull();
}
}
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for prefix query");
}
return new PrefixQueryBuilder(fieldName, value)
.rewrite(rewrite)
.boost(boost)
.queryName(queryName);
}
@Override
public String getWriteableName() {
return NAME;

View File

@ -1,93 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for prefix query
*/
public class PrefixQueryParser implements QueryParser<PrefixQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(PrefixQueryBuilder.NAME);
public static final ParseField PREFIX_FIELD = new ParseField("value", "prefix");
public static final ParseField REWRITE_FIELD = new ParseField("rewrite");
@Override
public PrefixQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = parser.currentName();
String value = null;
String rewrite = null;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
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 (parseContext.isDeprecatedSetting(currentFieldName)) {
// skip
} else if (token == XContentParser.Token.START_OBJECT) {
fieldName = currentFieldName;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, PREFIX_FIELD)) {
value = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, REWRITE_FIELD)) {
rewrite = parser.textOrNull();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[regexp] query does not support [" + currentFieldName + "]");
}
}
}
} else {
fieldName = currentFieldName;
value = parser.textOrNull();
}
}
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for prefix query");
}
return new PrefixQueryBuilder(fieldName, value)
.rewrite(rewrite)
.boost(boost)
.queryName(queryName);
}
@Override
public PrefixQueryBuilder getBuilderPrototype() {
return PrefixQueryBuilder.PROTOTYPE;
}
}

View File

@ -26,18 +26,22 @@ import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.automaton.Operations;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.query.support.QueryParsers;
import org.joda.time.DateTimeZone;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -54,6 +58,8 @@ import java.util.TreeMap;
public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQueryBuilder> {
public static final String NAME = "query_string";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final QueryStringQueryBuilder PROTOTYPE = new QueryStringQueryBuilder("");
public static final boolean DEFAULT_AUTO_GENERATE_PHRASE_QUERIES = false;
public static final int DEFAULT_MAX_DETERMINED_STATES = Operations.DEFAULT_MAX_DETERMINIZED_STATES;
@ -69,7 +75,32 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
public static final Operator DEFAULT_OPERATOR = Operator.OR;
public static final Locale DEFAULT_LOCALE = Locale.ROOT;
static final QueryStringQueryBuilder PROTOTYPE = new QueryStringQueryBuilder("");
private static final ParseField QUERY_FIELD = new ParseField("query");
private static final ParseField FIELDS_FIELD = new ParseField("fields");
private static final ParseField DEFAULT_FIELD_FIELD = new ParseField("default_field");
private static final ParseField DEFAULT_OPERATOR_FIELD = new ParseField("default_operator");
private static final ParseField ANALYZER_FIELD = new ParseField("analyzer");
private static final ParseField QUOTE_ANALYZER_FIELD = new ParseField("quote_analyzer");
private static final ParseField ALLOW_LEADING_WILDCARD_FIELD = new ParseField("allow_leading_wildcard");
private static final ParseField AUTO_GENERATED_PHRASE_QUERIES_FIELD = new ParseField("auto_generated_phrase_queries");
private static final ParseField MAX_DETERMINED_STATES_FIELD = new ParseField("max_determined_states");
private static final ParseField LOWERCASE_EXPANDED_TERMS_FIELD = new ParseField("lowercase_expanded_terms");
private static final ParseField ENABLE_POSITION_INCREMENTS_FIELD = new ParseField("enable_position_increment");
private static final ParseField ESCAPE_FIELD = new ParseField("escape");
private static final ParseField USE_DIS_MAX_FIELD = new ParseField("use_dis_max");
private static final ParseField FUZZY_PREFIX_LENGTH_FIELD = new ParseField("fuzzy_prefix_length");
private static final ParseField FUZZY_MAX_EXPANSIONS_FIELD = new ParseField("fuzzy_max_expansions");
private static final ParseField FUZZY_REWRITE_FIELD = new ParseField("fuzzy_rewrite");
private static final ParseField PHRASE_SLOP_FIELD = new ParseField("phrase_slop");
private static final ParseField TIE_BREAKER_FIELD = new ParseField("tie_breaker");
private static final ParseField ANALYZE_WILDCARD_FIELD = new ParseField("analyze_wildcard");
private static final ParseField REWRITE_FIELD = new ParseField("rewrite");
private static final ParseField MINIMUM_SHOULD_MATCH_FIELD = new ParseField("minimum_should_match");
private static final ParseField QUOTE_FIELD_SUFFIX_FIELD = new ParseField("quote_field_suffix");
private static final ParseField LENIENT_FIELD = new ParseField("lenient");
private static final ParseField LOCALE_FIELD = new ParseField("locale");
private static final ParseField TIME_ZONE_FIELD = new ParseField("time_zone");
private final String queryString;
@ -474,63 +505,227 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.field(QueryStringQueryParser.QUERY_FIELD.getPreferredName(), this.queryString);
builder.field(QUERY_FIELD.getPreferredName(), this.queryString);
if (this.defaultField != null) {
builder.field(QueryStringQueryParser.DEFAULT_FIELD_FIELD.getPreferredName(), this.defaultField);
builder.field(DEFAULT_FIELD_FIELD.getPreferredName(), this.defaultField);
}
builder.startArray(QueryStringQueryParser.FIELDS_FIELD.getPreferredName());
builder.startArray(FIELDS_FIELD.getPreferredName());
for (Map.Entry<String, Float> fieldEntry : this.fieldsAndWeights.entrySet()) {
builder.value(fieldEntry.getKey() + "^" + fieldEntry.getValue());
}
builder.endArray();
builder.field(QueryStringQueryParser.USE_DIS_MAX_FIELD.getPreferredName(), this.useDisMax);
builder.field(QueryStringQueryParser.TIE_BREAKER_FIELD.getPreferredName(), this.tieBreaker);
builder.field(QueryStringQueryParser.DEFAULT_OPERATOR_FIELD.getPreferredName(),
builder.field(USE_DIS_MAX_FIELD.getPreferredName(), this.useDisMax);
builder.field(TIE_BREAKER_FIELD.getPreferredName(), this.tieBreaker);
builder.field(DEFAULT_OPERATOR_FIELD.getPreferredName(),
this.defaultOperator.name().toLowerCase(Locale.ROOT));
if (this.analyzer != null) {
builder.field(QueryStringQueryParser.ANALYZER_FIELD.getPreferredName(), this.analyzer);
builder.field(ANALYZER_FIELD.getPreferredName(), this.analyzer);
}
if (this.quoteAnalyzer != null) {
builder.field(QueryStringQueryParser.QUOTE_ANALYZER_FIELD.getPreferredName(), this.quoteAnalyzer);
builder.field(QUOTE_ANALYZER_FIELD.getPreferredName(), this.quoteAnalyzer);
}
builder.field(QueryStringQueryParser.AUTO_GENERATED_PHRASE_QUERIES_FIELD.getPreferredName(), this.autoGeneratePhraseQueries);
builder.field(QueryStringQueryParser.MAX_DETERMINED_STATES_FIELD.getPreferredName(), this.maxDeterminizedStates);
builder.field(AUTO_GENERATED_PHRASE_QUERIES_FIELD.getPreferredName(), this.autoGeneratePhraseQueries);
builder.field(MAX_DETERMINED_STATES_FIELD.getPreferredName(), this.maxDeterminizedStates);
if (this.allowLeadingWildcard != null) {
builder.field(QueryStringQueryParser.ALLOW_LEADING_WILDCARD_FIELD.getPreferredName(), this.allowLeadingWildcard);
builder.field(ALLOW_LEADING_WILDCARD_FIELD.getPreferredName(), this.allowLeadingWildcard);
}
builder.field(QueryStringQueryParser.LOWERCASE_EXPANDED_TERMS_FIELD.getPreferredName(), this.lowercaseExpandedTerms);
builder.field(QueryStringQueryParser.ENABLE_POSITION_INCREMENTS_FIELD.getPreferredName(), this.enablePositionIncrements);
builder.field(LOWERCASE_EXPANDED_TERMS_FIELD.getPreferredName(), this.lowercaseExpandedTerms);
builder.field(ENABLE_POSITION_INCREMENTS_FIELD.getPreferredName(), this.enablePositionIncrements);
this.fuzziness.toXContent(builder, params);
builder.field(QueryStringQueryParser.FUZZY_PREFIX_LENGTH_FIELD.getPreferredName(), this.fuzzyPrefixLength);
builder.field(QueryStringQueryParser.FUZZY_MAX_EXPANSIONS_FIELD.getPreferredName(), this.fuzzyMaxExpansions);
builder.field(FUZZY_PREFIX_LENGTH_FIELD.getPreferredName(), this.fuzzyPrefixLength);
builder.field(FUZZY_MAX_EXPANSIONS_FIELD.getPreferredName(), this.fuzzyMaxExpansions);
if (this.fuzzyRewrite != null) {
builder.field(QueryStringQueryParser.FUZZY_REWRITE_FIELD.getPreferredName(), this.fuzzyRewrite);
builder.field(FUZZY_REWRITE_FIELD.getPreferredName(), this.fuzzyRewrite);
}
builder.field(QueryStringQueryParser.PHRASE_SLOP_FIELD.getPreferredName(), this.phraseSlop);
builder.field(PHRASE_SLOP_FIELD.getPreferredName(), this.phraseSlop);
if (this.analyzeWildcard != null) {
builder.field(QueryStringQueryParser.ANALYZE_WILDCARD_FIELD.getPreferredName(), this.analyzeWildcard);
builder.field(ANALYZE_WILDCARD_FIELD.getPreferredName(), this.analyzeWildcard);
}
if (this.rewrite != null) {
builder.field(QueryStringQueryParser.REWRITE_FIELD.getPreferredName(), this.rewrite);
builder.field(REWRITE_FIELD.getPreferredName(), this.rewrite);
}
if (this.minimumShouldMatch != null) {
builder.field(QueryStringQueryParser.MINIMUM_SHOULD_MATCH_FIELD.getPreferredName(), this.minimumShouldMatch);
builder.field(MINIMUM_SHOULD_MATCH_FIELD.getPreferredName(), this.minimumShouldMatch);
}
if (this.quoteFieldSuffix != null) {
builder.field(QueryStringQueryParser.QUOTE_FIELD_SUFFIX_FIELD.getPreferredName(), this.quoteFieldSuffix);
builder.field(QUOTE_FIELD_SUFFIX_FIELD.getPreferredName(), this.quoteFieldSuffix);
}
if (this.lenient != null) {
builder.field(QueryStringQueryParser.LENIENT_FIELD.getPreferredName(), this.lenient);
builder.field(LENIENT_FIELD.getPreferredName(), this.lenient);
}
builder.field(QueryStringQueryParser.LOCALE_FIELD.getPreferredName(), this.locale.toLanguageTag());
builder.field(LOCALE_FIELD.getPreferredName(), this.locale.toLanguageTag());
if (this.timeZone != null) {
builder.field(QueryStringQueryParser.TIME_ZONE_FIELD.getPreferredName(), this.timeZone.getID());
builder.field(TIME_ZONE_FIELD.getPreferredName(), this.timeZone.getID());
}
builder.field(QueryStringQueryParser.ESCAPE_FIELD.getPreferredName(), this.escape);
builder.field(ESCAPE_FIELD.getPreferredName(), this.escape);
printBoostAndQueryName(builder);
builder.endObject();
}
public static QueryStringQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String currentFieldName = null;
XContentParser.Token token;
String queryString = null;
String defaultField = null;
String analyzer = null;
String quoteAnalyzer = null;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
boolean autoGeneratePhraseQueries = QueryStringQueryBuilder.DEFAULT_AUTO_GENERATE_PHRASE_QUERIES;
int maxDeterminizedStates = QueryStringQueryBuilder.DEFAULT_MAX_DETERMINED_STATES;
boolean lowercaseExpandedTerms = QueryStringQueryBuilder.DEFAULT_LOWERCASE_EXPANDED_TERMS;
boolean enablePositionIncrements = QueryStringQueryBuilder.DEFAULT_ENABLE_POSITION_INCREMENTS;
boolean escape = QueryStringQueryBuilder.DEFAULT_ESCAPE;
boolean useDisMax = QueryStringQueryBuilder.DEFAULT_USE_DIS_MAX;
int fuzzyPrefixLength = QueryStringQueryBuilder.DEFAULT_FUZZY_PREFIX_LENGTH;
int fuzzyMaxExpansions = QueryStringQueryBuilder.DEFAULT_FUZZY_MAX_EXPANSIONS;
int phraseSlop = QueryStringQueryBuilder.DEFAULT_PHRASE_SLOP;
float tieBreaker = QueryStringQueryBuilder.DEFAULT_TIE_BREAKER;
Boolean analyzeWildcard = null;
Boolean allowLeadingWildcard = null;
String minimumShouldMatch = null;
String quoteFieldSuffix = null;
Boolean lenient = null;
Operator defaultOperator = QueryStringQueryBuilder.DEFAULT_OPERATOR;
String timeZone = null;
Locale locale = QueryStringQueryBuilder.DEFAULT_LOCALE;
Fuzziness fuzziness = QueryStringQueryBuilder.DEFAULT_FUZZINESS;
String fuzzyRewrite = null;
String rewrite = null;
Map<String, Float> fieldsAndWeights = new HashMap<>();
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 (parseContext.parseFieldMatcher().match(currentFieldName, FIELDS_FIELD)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
String fField = null;
float fBoost = AbstractQueryBuilder.DEFAULT_BOOST;
char[] text = parser.textCharacters();
int end = parser.textOffset() + parser.textLength();
for (int i = parser.textOffset(); i < end; i++) {
if (text[i] == '^') {
int relativeLocation = i - parser.textOffset();
fField = new String(text, parser.textOffset(), relativeLocation);
fBoost = Float.parseFloat(new String(text, i + 1, parser.textLength() - relativeLocation - 1));
break;
}
}
if (fField == null) {
fField = parser.text();
}
fieldsAndWeights.put(fField, fBoost);
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + QueryStringQueryBuilder.NAME +
"] query does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
queryString = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, DEFAULT_FIELD_FIELD)) {
defaultField = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, DEFAULT_OPERATOR_FIELD)) {
defaultOperator = Operator.fromString(parser.text());
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ANALYZER_FIELD)) {
analyzer = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, QUOTE_ANALYZER_FIELD)) {
quoteAnalyzer = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ALLOW_LEADING_WILDCARD_FIELD)) {
allowLeadingWildcard = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AUTO_GENERATED_PHRASE_QUERIES_FIELD)) {
autoGeneratePhraseQueries = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MAX_DETERMINED_STATES_FIELD)) {
maxDeterminizedStates = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LOWERCASE_EXPANDED_TERMS_FIELD)) {
lowercaseExpandedTerms = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ENABLE_POSITION_INCREMENTS_FIELD)) {
enablePositionIncrements = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ESCAPE_FIELD)) {
escape = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, USE_DIS_MAX_FIELD)) {
useDisMax = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FUZZY_PREFIX_LENGTH_FIELD)) {
fuzzyPrefixLength = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FUZZY_MAX_EXPANSIONS_FIELD)) {
fuzzyMaxExpansions = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FUZZY_REWRITE_FIELD)) {
fuzzyRewrite = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, PHRASE_SLOP_FIELD)) {
phraseSlop = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Fuzziness.FIELD)) {
fuzziness = Fuzziness.parse(parser);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TIE_BREAKER_FIELD)) {
tieBreaker = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ANALYZE_WILDCARD_FIELD)) {
analyzeWildcard = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, REWRITE_FIELD)) {
rewrite = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MINIMUM_SHOULD_MATCH_FIELD)) {
minimumShouldMatch = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, QUOTE_FIELD_SUFFIX_FIELD)) {
quoteFieldSuffix = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LENIENT_FIELD)) {
lenient = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LOCALE_FIELD)) {
String localeStr = parser.text();
locale = Locale.forLanguageTag(localeStr);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TIME_ZONE_FIELD)) {
try {
timeZone = parser.text();
} catch (IllegalArgumentException e) {
throw new ParsingException(parser.getTokenLocation(), "[" + QueryStringQueryBuilder.NAME +
"] time_zone [" + parser.text() + "] is unknown");
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + QueryStringQueryBuilder.NAME +
"] query does not support [" + currentFieldName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + QueryStringQueryBuilder.NAME +
"] unknown token [" + token + "] after [" + currentFieldName + "]");
}
}
if (queryString == null) {
throw new ParsingException(parser.getTokenLocation(), "[" + QueryStringQueryBuilder.NAME + "] must be provided with a [query]");
}
QueryStringQueryBuilder queryStringQuery = new QueryStringQueryBuilder(queryString);
queryStringQuery.fields(fieldsAndWeights);
queryStringQuery.defaultField(defaultField);
queryStringQuery.defaultOperator(defaultOperator);
queryStringQuery.analyzer(analyzer);
queryStringQuery.quoteAnalyzer(quoteAnalyzer);
queryStringQuery.allowLeadingWildcard(allowLeadingWildcard);
queryStringQuery.autoGeneratePhraseQueries(autoGeneratePhraseQueries);
queryStringQuery.maxDeterminizedStates(maxDeterminizedStates);
queryStringQuery.lowercaseExpandedTerms(lowercaseExpandedTerms);
queryStringQuery.enablePositionIncrements(enablePositionIncrements);
queryStringQuery.escape(escape);
queryStringQuery.useDisMax(useDisMax);
queryStringQuery.fuzzyPrefixLength(fuzzyPrefixLength);
queryStringQuery.fuzzyMaxExpansions(fuzzyMaxExpansions);
queryStringQuery.fuzzyRewrite(fuzzyRewrite);
queryStringQuery.phraseSlop(phraseSlop);
queryStringQuery.fuzziness(fuzziness);
queryStringQuery.tieBreaker(tieBreaker);
queryStringQuery.analyzeWildcard(analyzeWildcard);
queryStringQuery.rewrite(rewrite);
queryStringQuery.minimumShouldMatch(minimumShouldMatch);
queryStringQuery.quoteFieldSuffix(quoteFieldSuffix);
queryStringQuery.lenient(lenient);
queryStringQuery.timeZone(timeZone);
queryStringQuery.locale(locale);
queryStringQuery.boost(boost);
queryStringQuery.queryName(queryName);
return queryStringQuery;
}
@Override
public String getWriteableName() {
return NAME;

View File

@ -1,233 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* Parser for query_string query
*/
public class QueryStringQueryParser implements QueryParser {
public static final ParseField QUERY_NAME_FIELD = new ParseField(QueryStringQueryBuilder.NAME);
public static final ParseField QUERY_FIELD = new ParseField("query");
public static final ParseField FIELDS_FIELD = new ParseField("fields");
public static final ParseField DEFAULT_FIELD_FIELD = new ParseField("default_field");
public static final ParseField DEFAULT_OPERATOR_FIELD = new ParseField("default_operator");
public static final ParseField ANALYZER_FIELD = new ParseField("analyzer");
public static final ParseField QUOTE_ANALYZER_FIELD = new ParseField("quote_analyzer");
public static final ParseField ALLOW_LEADING_WILDCARD_FIELD = new ParseField("allow_leading_wildcard");
public static final ParseField AUTO_GENERATED_PHRASE_QUERIES_FIELD = new ParseField("auto_generated_phrase_queries");
public static final ParseField MAX_DETERMINED_STATES_FIELD = new ParseField("max_determined_states");
public static final ParseField LOWERCASE_EXPANDED_TERMS_FIELD = new ParseField("lowercase_expanded_terms");
public static final ParseField ENABLE_POSITION_INCREMENTS_FIELD = new ParseField("enable_position_increment");
public static final ParseField ESCAPE_FIELD = new ParseField("escape");
public static final ParseField USE_DIS_MAX_FIELD = new ParseField("use_dis_max");
public static final ParseField FUZZY_PREFIX_LENGTH_FIELD = new ParseField("fuzzy_prefix_length");
public static final ParseField FUZZY_MAX_EXPANSIONS_FIELD = new ParseField("fuzzy_max_expansions");
public static final ParseField FUZZY_REWRITE_FIELD = new ParseField("fuzzy_rewrite");
public static final ParseField PHRASE_SLOP_FIELD = new ParseField("phrase_slop");
public static final ParseField TIE_BREAKER_FIELD = new ParseField("tie_breaker");
public static final ParseField ANALYZE_WILDCARD_FIELD = new ParseField("analyze_wildcard");
public static final ParseField REWRITE_FIELD = new ParseField("rewrite");
public static final ParseField MINIMUM_SHOULD_MATCH_FIELD = new ParseField("minimum_should_match");
public static final ParseField QUOTE_FIELD_SUFFIX_FIELD = new ParseField("quote_field_suffix");
public static final ParseField LENIENT_FIELD = new ParseField("lenient");
public static final ParseField LOCALE_FIELD = new ParseField("locale");
public static final ParseField TIME_ZONE_FIELD = new ParseField("time_zone");
@Override
public QueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String currentFieldName = null;
XContentParser.Token token;
String queryString = null;
String defaultField = null;
String analyzer = null;
String quoteAnalyzer = null;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
boolean autoGeneratePhraseQueries = QueryStringQueryBuilder.DEFAULT_AUTO_GENERATE_PHRASE_QUERIES;
int maxDeterminizedStates = QueryStringQueryBuilder.DEFAULT_MAX_DETERMINED_STATES;
boolean lowercaseExpandedTerms = QueryStringQueryBuilder.DEFAULT_LOWERCASE_EXPANDED_TERMS;
boolean enablePositionIncrements = QueryStringQueryBuilder.DEFAULT_ENABLE_POSITION_INCREMENTS;
boolean escape = QueryStringQueryBuilder.DEFAULT_ESCAPE;
boolean useDisMax = QueryStringQueryBuilder.DEFAULT_USE_DIS_MAX;
int fuzzyPrefixLength = QueryStringQueryBuilder.DEFAULT_FUZZY_PREFIX_LENGTH;
int fuzzyMaxExpansions = QueryStringQueryBuilder.DEFAULT_FUZZY_MAX_EXPANSIONS;
int phraseSlop = QueryStringQueryBuilder.DEFAULT_PHRASE_SLOP;
float tieBreaker = QueryStringQueryBuilder.DEFAULT_TIE_BREAKER;
Boolean analyzeWildcard = null;
Boolean allowLeadingWildcard = null;
String minimumShouldMatch = null;
String quoteFieldSuffix = null;
Boolean lenient = null;
Operator defaultOperator = QueryStringQueryBuilder.DEFAULT_OPERATOR;
String timeZone = null;
Locale locale = QueryStringQueryBuilder.DEFAULT_LOCALE;
Fuzziness fuzziness = QueryStringQueryBuilder.DEFAULT_FUZZINESS;
String fuzzyRewrite = null;
String rewrite = null;
Map<String, Float> fieldsAndWeights = new HashMap<>();
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 (parseContext.parseFieldMatcher().match(currentFieldName, FIELDS_FIELD)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
String fField = null;
float fBoost = AbstractQueryBuilder.DEFAULT_BOOST;
char[] text = parser.textCharacters();
int end = parser.textOffset() + parser.textLength();
for (int i = parser.textOffset(); i < end; i++) {
if (text[i] == '^') {
int relativeLocation = i - parser.textOffset();
fField = new String(text, parser.textOffset(), relativeLocation);
fBoost = Float.parseFloat(new String(text, i + 1, parser.textLength() - relativeLocation - 1));
break;
}
}
if (fField == null) {
fField = parser.text();
}
fieldsAndWeights.put(fField, fBoost);
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + QueryStringQueryBuilder.NAME +
"] query does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, QUERY_FIELD)) {
queryString = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, DEFAULT_FIELD_FIELD)) {
defaultField = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, DEFAULT_OPERATOR_FIELD)) {
defaultOperator = Operator.fromString(parser.text());
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ANALYZER_FIELD)) {
analyzer = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, QUOTE_ANALYZER_FIELD)) {
quoteAnalyzer = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ALLOW_LEADING_WILDCARD_FIELD)) {
allowLeadingWildcard = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AUTO_GENERATED_PHRASE_QUERIES_FIELD)) {
autoGeneratePhraseQueries = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MAX_DETERMINED_STATES_FIELD)) {
maxDeterminizedStates = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LOWERCASE_EXPANDED_TERMS_FIELD)) {
lowercaseExpandedTerms = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ENABLE_POSITION_INCREMENTS_FIELD)) {
enablePositionIncrements = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ESCAPE_FIELD)) {
escape = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, USE_DIS_MAX_FIELD)) {
useDisMax = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FUZZY_PREFIX_LENGTH_FIELD)) {
fuzzyPrefixLength = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FUZZY_MAX_EXPANSIONS_FIELD)) {
fuzzyMaxExpansions = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FUZZY_REWRITE_FIELD)) {
fuzzyRewrite = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, PHRASE_SLOP_FIELD)) {
phraseSlop = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, Fuzziness.FIELD)) {
fuzziness = Fuzziness.parse(parser);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TIE_BREAKER_FIELD)) {
tieBreaker = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, ANALYZE_WILDCARD_FIELD)) {
analyzeWildcard = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, REWRITE_FIELD)) {
rewrite = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MINIMUM_SHOULD_MATCH_FIELD)) {
minimumShouldMatch = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, QUOTE_FIELD_SUFFIX_FIELD)) {
quoteFieldSuffix = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LENIENT_FIELD)) {
lenient = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LOCALE_FIELD)) {
String localeStr = parser.text();
locale = Locale.forLanguageTag(localeStr);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TIME_ZONE_FIELD)) {
try {
timeZone = parser.text();
} catch (IllegalArgumentException e) {
throw new ParsingException(parser.getTokenLocation(), "[" + QueryStringQueryBuilder.NAME +
"] time_zone [" + parser.text() + "] is unknown");
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + QueryStringQueryBuilder.NAME +
"] query does not support [" + currentFieldName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[" + QueryStringQueryBuilder.NAME +
"] unknown token [" + token + "] after [" + currentFieldName + "]");
}
}
if (queryString == null) {
throw new ParsingException(parser.getTokenLocation(), "[" + QueryStringQueryBuilder.NAME + "] must be provided with a [query]");
}
QueryStringQueryBuilder queryStringQuery = new QueryStringQueryBuilder(queryString);
queryStringQuery.fields(fieldsAndWeights);
queryStringQuery.defaultField(defaultField);
queryStringQuery.defaultOperator(defaultOperator);
queryStringQuery.analyzer(analyzer);
queryStringQuery.quoteAnalyzer(quoteAnalyzer);
queryStringQuery.allowLeadingWildcard(allowLeadingWildcard);
queryStringQuery.autoGeneratePhraseQueries(autoGeneratePhraseQueries);
queryStringQuery.maxDeterminizedStates(maxDeterminizedStates);
queryStringQuery.lowercaseExpandedTerms(lowercaseExpandedTerms);
queryStringQuery.enablePositionIncrements(enablePositionIncrements);
queryStringQuery.escape(escape);
queryStringQuery.useDisMax(useDisMax);
queryStringQuery.fuzzyPrefixLength(fuzzyPrefixLength);
queryStringQuery.fuzzyMaxExpansions(fuzzyMaxExpansions);
queryStringQuery.fuzzyRewrite(fuzzyRewrite);
queryStringQuery.phraseSlop(phraseSlop);
queryStringQuery.fuzziness(fuzziness);
queryStringQuery.tieBreaker(tieBreaker);
queryStringQuery.analyzeWildcard(analyzeWildcard);
queryStringQuery.rewrite(rewrite);
queryStringQuery.minimumShouldMatch(minimumShouldMatch);
queryStringQuery.quoteFieldSuffix(quoteFieldSuffix);
queryStringQuery.lenient(lenient);
queryStringQuery.timeZone(timeZone);
queryStringQuery.locale(locale);
queryStringQuery.boost(boost);
queryStringQuery.queryName(queryName);
return queryStringQuery;
}
@Override
public QueryStringQueryBuilder getBuilderPrototype() {
return QueryStringQueryBuilder.PROTOTYPE;
}
}

View File

@ -23,6 +23,8 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
@ -31,6 +33,7 @@ import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.core.DateFieldMapper;
@ -43,12 +46,26 @@ import java.util.Objects;
* A Query that matches documents within an range of terms.
*/
public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> implements MultiTermQueryBuilder<RangeQueryBuilder> {
public static final String NAME = "range";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final RangeQueryBuilder PROTOTYPE = new RangeQueryBuilder("field");
public static final boolean DEFAULT_INCLUDE_UPPER = true;
public static final boolean DEFAULT_INCLUDE_LOWER = true;
public static final String NAME = "range";
private static final ParseField FIELDDATA_FIELD = new ParseField("fielddata").withAllDeprecated("[no replacement]");
private static final ParseField NAME_FIELD = new ParseField("_name")
.withAllDeprecated("query name is not supported in short version of range query");
private static final ParseField LTE_FIELD = new ParseField("lte", "le");
private static final ParseField GTE_FIELD = new ParseField("gte", "ge");
private static final ParseField FROM_FIELD = new ParseField("from");
private static final ParseField TO_FIELD = new ParseField("to");
private static final ParseField INCLUDE_LOWER_FIELD = new ParseField("include_lower");
private static final ParseField INCLUDE_UPPER_FIELD = new ParseField("include_upper");
private static final ParseField GT_FIELD = new ParseField("gt");
private static final ParseField LT_FIELD = new ParseField("lt");
private static final ParseField TIME_ZONE_FIELD = new ParseField("time_zone");
private static final ParseField FORMAT_FIELD = new ParseField("format");
private final String fieldName;
@ -64,8 +81,6 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
private FormatDateTimeFormatter format;
static final RangeQueryBuilder PROTOTYPE = new RangeQueryBuilder("field");
/**
* A Query that matches documents within an range of terms.
*
@ -88,7 +103,7 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
/**
* The from part of the range query. Null indicates unbounded.
* In case lower bound is assigned to a string, we internally convert it to a {@link BytesRef} because
* in {@link RangeQueryParser} field are later parsed as {@link BytesRef} and we need internal representation
* in {@link RangeQueryBuilder} field are later parsed as {@link BytesRef} and we need internal representation
* of query to be equal regardless of whether it was created from XContent or via Java API.
*/
public RangeQueryBuilder from(Object from, boolean includeLower) {
@ -144,7 +159,7 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
/**
* Gets the upper range value for this query.
* In case upper bound is assigned to a string, we internally convert it to a {@link BytesRef} because
* in {@link RangeQueryParser} field are later parsed as {@link BytesRef} and we need internal representation
* in {@link RangeQueryBuilder} field are later parsed as {@link BytesRef} and we need internal representation
* of query to be equal regardless of whether it was created from XContent or via Java API.
*/
public Object to() {
@ -235,21 +250,108 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.startObject(fieldName);
builder.field(RangeQueryParser.FROM_FIELD.getPreferredName(), convertToStringIfBytesRef(this.from));
builder.field(RangeQueryParser.TO_FIELD.getPreferredName(), convertToStringIfBytesRef(this.to));
builder.field(RangeQueryParser.INCLUDE_LOWER_FIELD.getPreferredName(), includeLower);
builder.field(RangeQueryParser.INCLUDE_UPPER_FIELD.getPreferredName(), includeUpper);
builder.field(FROM_FIELD.getPreferredName(), convertToStringIfBytesRef(this.from));
builder.field(TO_FIELD.getPreferredName(), convertToStringIfBytesRef(this.to));
builder.field(INCLUDE_LOWER_FIELD.getPreferredName(), includeLower);
builder.field(INCLUDE_UPPER_FIELD.getPreferredName(), includeUpper);
if (timeZone != null) {
builder.field(RangeQueryParser.TIME_ZONE_FIELD.getPreferredName(), timeZone.getID());
builder.field(TIME_ZONE_FIELD.getPreferredName(), timeZone.getID());
}
if (format != null) {
builder.field(RangeQueryParser.FORMAT_FIELD.getPreferredName(), format.format());
builder.field(FORMAT_FIELD.getPreferredName(), format.format());
}
printBoostAndQueryName(builder);
builder.endObject();
builder.endObject();
}
public static RangeQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = null;
Object from = null;
Object to = null;
boolean includeLower = RangeQueryBuilder.DEFAULT_INCLUDE_LOWER;
boolean includeUpper = RangeQueryBuilder.DEFAULT_INCLUDE_UPPER;
String timeZone = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
String format = null;
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 (parseContext.isDeprecatedSetting(currentFieldName)) {
// skip
} else if (token == XContentParser.Token.START_OBJECT) {
fieldName = currentFieldName;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, FROM_FIELD)) {
from = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TO_FIELD)) {
to = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, INCLUDE_LOWER_FIELD)) {
includeLower = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, INCLUDE_UPPER_FIELD)) {
includeUpper = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, GT_FIELD)) {
from = parser.objectBytes();
includeLower = false;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, GTE_FIELD)) {
from = parser.objectBytes();
includeLower = true;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LT_FIELD)) {
to = parser.objectBytes();
includeUpper = false;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LTE_FIELD)) {
to = parser.objectBytes();
includeUpper = true;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TIME_ZONE_FIELD)) {
timeZone = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FORMAT_FIELD)) {
format = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[range] query does not support [" + currentFieldName + "]");
}
}
}
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, NAME_FIELD)) {
queryName = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FIELDDATA_FIELD)) {
// ignore
} else {
throw new ParsingException(parser.getTokenLocation(), "[range] query does not support [" + currentFieldName + "]");
}
}
}
RangeQueryBuilder rangeQuery = new RangeQueryBuilder(fieldName);
rangeQuery.from(from);
rangeQuery.to(to);
rangeQuery.includeLower(includeLower);
rangeQuery.includeUpper(includeUpper);
if (timeZone != null) {
rangeQuery.timeZone(timeZone);
}
rangeQuery.boost(boost);
rangeQuery.queryName(queryName);
if (format != null) {
rangeQuery.format(format);
}
return rangeQuery;
}
@Override
public String getWriteableName() {
return NAME;

View File

@ -1,140 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for range query
*/
public class RangeQueryParser implements QueryParser<RangeQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(RangeQueryBuilder.NAME);
public static final ParseField FIELDDATA_FIELD = new ParseField("fielddata").withAllDeprecated("[no replacement]");
public static final ParseField NAME_FIELD = new ParseField("_name")
.withAllDeprecated("query name is not supported in short version of range query");
public static final ParseField LTE_FIELD = new ParseField("lte", "le");
public static final ParseField GTE_FIELD = new ParseField("gte", "ge");
public static final ParseField FROM_FIELD = new ParseField("from");
public static final ParseField TO_FIELD = new ParseField("to");
public static final ParseField INCLUDE_LOWER_FIELD = new ParseField("include_lower");
public static final ParseField INCLUDE_UPPER_FIELD = new ParseField("include_upper");
public static final ParseField GT_FIELD = new ParseField("gt");
public static final ParseField LT_FIELD = new ParseField("lt");
public static final ParseField TIME_ZONE_FIELD = new ParseField("time_zone");
public static final ParseField FORMAT_FIELD = new ParseField("format");
@Override
public RangeQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = null;
Object from = null;
Object to = null;
boolean includeLower = RangeQueryBuilder.DEFAULT_INCLUDE_LOWER;
boolean includeUpper = RangeQueryBuilder.DEFAULT_INCLUDE_UPPER;
String timeZone = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
String format = null;
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 (parseContext.isDeprecatedSetting(currentFieldName)) {
// skip
} else if (token == XContentParser.Token.START_OBJECT) {
fieldName = currentFieldName;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, FROM_FIELD)) {
from = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TO_FIELD)) {
to = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, INCLUDE_LOWER_FIELD)) {
includeLower = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, INCLUDE_UPPER_FIELD)) {
includeUpper = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, GT_FIELD)) {
from = parser.objectBytes();
includeLower = false;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, GTE_FIELD)) {
from = parser.objectBytes();
includeLower = true;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LT_FIELD)) {
to = parser.objectBytes();
includeUpper = false;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LTE_FIELD)) {
to = parser.objectBytes();
includeUpper = true;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, TIME_ZONE_FIELD)) {
timeZone = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FORMAT_FIELD)) {
format = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[range] query does not support [" + currentFieldName + "]");
}
}
}
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, NAME_FIELD)) {
queryName = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FIELDDATA_FIELD)) {
// ignore
} else {
throw new ParsingException(parser.getTokenLocation(), "[range] query does not support [" + currentFieldName + "]");
}
}
}
RangeQueryBuilder rangeQuery = new RangeQueryBuilder(fieldName);
rangeQuery.from(from);
rangeQuery.to(to);
rangeQuery.includeLower(includeLower);
rangeQuery.includeUpper(includeUpper);
if (timeZone != null) {
rangeQuery.timeZone(timeZone);
}
rangeQuery.boost(boost);
rangeQuery.queryName(queryName);
if (format != null) {
rangeQuery.format(format);
}
return rangeQuery;
}
@Override
public RangeQueryBuilder getBuilderPrototype() {
return RangeQueryBuilder.PROTOTYPE;
}
}

View File

@ -24,11 +24,14 @@ import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RegexpQuery;
import org.apache.lucene.util.automaton.Operations;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.query.support.QueryParsers;
@ -41,11 +44,20 @@ import java.util.Objects;
public class RegexpQueryBuilder extends AbstractQueryBuilder<RegexpQueryBuilder> implements MultiTermQueryBuilder<RegexpQueryBuilder> {
public static final String NAME = "regexp";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final RegexpQueryBuilder PROTOTYPE = new RegexpQueryBuilder("field", "value");
public static final int DEFAULT_FLAGS_VALUE = RegexpFlag.ALL.value();
public static final int DEFAULT_MAX_DETERMINIZED_STATES = Operations.DEFAULT_MAX_DETERMINIZED_STATES;
private static final ParseField NAME_FIELD = new ParseField("_name")
.withAllDeprecated("query name is not supported in short version of regexp query");
private static final ParseField FLAGS_VALUE_FIELD = new ParseField("flags_value");
private static final ParseField MAX_DETERMINIZED_STATES_FIELD = new ParseField("max_determinized_states");
private static final ParseField FLAGS_FIELD = new ParseField("flags");
private static final ParseField REWRITE_FIELD = new ParseField("rewrite");
private static final ParseField VALUE_FIELD = new ParseField("value");
private final String fieldName;
private final String value;
@ -56,8 +68,6 @@ public class RegexpQueryBuilder extends AbstractQueryBuilder<RegexpQueryBuilder>
private String rewrite;
static final RegexpQueryBuilder PROTOTYPE = new RegexpQueryBuilder("field", "value");
/**
* Constructs a new regex query.
*
@ -138,17 +148,83 @@ public class RegexpQueryBuilder extends AbstractQueryBuilder<RegexpQueryBuilder>
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.startObject(fieldName);
builder.field(RegexpQueryParser.VALUE_FIELD.getPreferredName(), this.value);
builder.field(RegexpQueryParser.FLAGS_VALUE_FIELD.getPreferredName(), flagsValue);
builder.field(RegexpQueryParser.MAX_DETERMINIZED_STATES_FIELD.getPreferredName(), maxDeterminizedStates);
builder.field(VALUE_FIELD.getPreferredName(), this.value);
builder.field(FLAGS_VALUE_FIELD.getPreferredName(), flagsValue);
builder.field(MAX_DETERMINIZED_STATES_FIELD.getPreferredName(), maxDeterminizedStates);
if (rewrite != null) {
builder.field(RegexpQueryParser.REWRITE_FIELD.getPreferredName(), rewrite);
builder.field(REWRITE_FIELD.getPreferredName(), rewrite);
}
printBoostAndQueryName(builder);
builder.endObject();
builder.endObject();
}
public static RegexpQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = parser.currentName();
String rewrite = null;
String value = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
int flagsValue = RegexpQueryBuilder.DEFAULT_FLAGS_VALUE;
int maxDeterminizedStates = RegexpQueryBuilder.DEFAULT_MAX_DETERMINIZED_STATES;
String queryName = null;
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 (parseContext.isDeprecatedSetting(currentFieldName)) {
// skip
} else if (token == XContentParser.Token.START_OBJECT) {
fieldName = currentFieldName;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, VALUE_FIELD)) {
value = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, REWRITE_FIELD)) {
rewrite = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FLAGS_FIELD)) {
String flags = parser.textOrNull();
flagsValue = RegexpFlag.resolveValue(flags);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MAX_DETERMINIZED_STATES_FIELD)) {
maxDeterminizedStates = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FLAGS_VALUE_FIELD)) {
flagsValue = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[regexp] query does not support [" + currentFieldName + "]");
}
}
}
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, NAME_FIELD)) {
queryName = parser.text();
} else {
fieldName = currentFieldName;
value = parser.textOrNull();
}
}
}
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for regexp query");
}
return new RegexpQueryBuilder(fieldName, value)
.flags(flagsValue)
.maxDeterminizedStates(maxDeterminizedStates)
.rewrite(rewrite)
.boost(boost)
.queryName(queryName);
}
@Override
public String getWriteableName() {
return NAME;

View File

@ -1,113 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for regexp query
*/
public class RegexpQueryParser implements QueryParser<RegexpQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(RegexpQueryBuilder.NAME);
public static final ParseField NAME_FIELD = new ParseField("_name")
.withAllDeprecated("query name is not supported in short version of regexp query");
public static final ParseField FLAGS_VALUE_FIELD = new ParseField("flags_value");
public static final ParseField MAX_DETERMINIZED_STATES_FIELD = new ParseField("max_determinized_states");
public static final ParseField FLAGS_FIELD = new ParseField("flags");
public static final ParseField REWRITE_FIELD = new ParseField("rewrite");
public static final ParseField VALUE_FIELD = new ParseField("value");
@Override
public RegexpQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = parser.currentName();
String rewrite = null;
String value = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
int flagsValue = RegexpQueryBuilder.DEFAULT_FLAGS_VALUE;
int maxDeterminizedStates = RegexpQueryBuilder.DEFAULT_MAX_DETERMINIZED_STATES;
String queryName = null;
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 (parseContext.isDeprecatedSetting(currentFieldName)) {
// skip
} else if (token == XContentParser.Token.START_OBJECT) {
fieldName = currentFieldName;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, VALUE_FIELD)) {
value = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, REWRITE_FIELD)) {
rewrite = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FLAGS_FIELD)) {
String flags = parser.textOrNull();
flagsValue = RegexpFlag.resolveValue(flags);
} else if (parseContext.parseFieldMatcher().match(currentFieldName, MAX_DETERMINIZED_STATES_FIELD)) {
maxDeterminizedStates = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FLAGS_VALUE_FIELD)) {
flagsValue = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[regexp] query does not support [" + currentFieldName + "]");
}
}
}
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, NAME_FIELD)) {
queryName = parser.text();
} else {
fieldName = currentFieldName;
value = parser.textOrNull();
}
}
}
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for regexp query");
}
return new RegexpQueryBuilder(fieldName, value)
.flags(flagsValue)
.maxDeterminizedStates(maxDeterminizedStates)
.rewrite(rewrite)
.boost(boost)
.queryName(queryName);
}
@Override
public RegexpQueryBuilder getBuilderPrototype() {
return RegexpQueryBuilder.PROTOTYPE;
}
}

View File

@ -22,9 +22,12 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.spans.SpanContainingQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
@ -36,10 +39,15 @@ public class SpanContainingQueryBuilder extends AbstractQueryBuilder<SpanContain
implements SpanQueryBuilder<SpanContainingQueryBuilder> {
public static final String NAME = "span_containing";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final SpanContainingQueryBuilder PROTOTYPE =
new SpanContainingQueryBuilder(SpanTermQueryBuilder.PROTOTYPE, SpanTermQueryBuilder.PROTOTYPE);
private static final ParseField BIG_FIELD = new ParseField("big");
private static final ParseField LITTLE_FIELD = new ParseField("little");
private final SpanQueryBuilder big;
private final SpanQueryBuilder little;
static final SpanContainingQueryBuilder PROTOTYPE =
new SpanContainingQueryBuilder(SpanTermQueryBuilder.PROTOTYPE, SpanTermQueryBuilder.PROTOTYPE);
/**
* @param big the big clause, it must enclose {@code little} for a match.
@ -73,14 +81,58 @@ public class SpanContainingQueryBuilder extends AbstractQueryBuilder<SpanContain
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.field(SpanContainingQueryParser.BIG_FIELD.getPreferredName());
builder.field(BIG_FIELD.getPreferredName());
big.toXContent(builder, params);
builder.field(SpanContainingQueryParser.LITTLE_FIELD.getPreferredName());
builder.field(LITTLE_FIELD.getPreferredName());
little.toXContent(builder, params);
printBoostAndQueryName(builder);
builder.endObject();
}
public static SpanContainingQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
SpanQueryBuilder<?> big = null;
SpanQueryBuilder<?> little = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, BIG_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder<?>)) {
throw new ParsingException(parser.getTokenLocation(), "span_containing [big] must be of type span query");
}
big = (SpanQueryBuilder<?>) query;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LITTLE_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder<?>)) {
throw new ParsingException(parser.getTokenLocation(), "span_containing [little] must be of type span query");
}
little = (SpanQueryBuilder<?>) query;
} else {
throw new ParsingException(parser.getTokenLocation(),
"[span_containing] query does not support [" + currentFieldName + "]");
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[span_containing] query does not support [" + currentFieldName + "]");
}
}
SpanContainingQueryBuilder query = new SpanContainingQueryBuilder(big, little);
query.boost(boost).queryName(queryName);
return query;
}
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
Query innerBig = big.toQuery(context);

View File

@ -1,86 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for span_containing query
*/
public class SpanContainingQueryParser implements QueryParser<SpanContainingQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(SpanContainingQueryBuilder.NAME);
public static final ParseField BIG_FIELD = new ParseField("big");
public static final ParseField LITTLE_FIELD = new ParseField("little");
@Override
public SpanContainingQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
SpanQueryBuilder<?> big = null;
SpanQueryBuilder<?> little = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, BIG_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder<?>)) {
throw new ParsingException(parser.getTokenLocation(), "span_containing [big] must be of type span query");
}
big = (SpanQueryBuilder<?>) query;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LITTLE_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder<?>)) {
throw new ParsingException(parser.getTokenLocation(), "span_containing [little] must be of type span query");
}
little = (SpanQueryBuilder<?>) query;
} else {
throw new ParsingException(parser.getTokenLocation(),
"[span_containing] query does not support [" + currentFieldName + "]");
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[span_containing] query does not support [" + currentFieldName + "]");
}
}
SpanContainingQueryBuilder query = new SpanContainingQueryBuilder(big, little);
query.boost(boost).queryName(queryName);
return query;
}
@Override
public SpanContainingQueryBuilder getBuilderPrototype() {
return SpanContainingQueryBuilder.PROTOTYPE;
}
}

View File

@ -22,9 +22,12 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.spans.SpanFirstQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
@ -32,13 +35,16 @@ import java.util.Objects;
public class SpanFirstQueryBuilder extends AbstractQueryBuilder<SpanFirstQueryBuilder> implements SpanQueryBuilder<SpanFirstQueryBuilder>{
public static final String NAME = "span_first";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final SpanFirstQueryBuilder PROTOTYPE = new SpanFirstQueryBuilder(SpanTermQueryBuilder.PROTOTYPE, 0);
private static final ParseField MATCH_FIELD = new ParseField("match");
private static final ParseField END_FIELD = new ParseField("end");
private final SpanQueryBuilder matchBuilder;
private final int end;
static final SpanFirstQueryBuilder PROTOTYPE = new SpanFirstQueryBuilder(SpanTermQueryBuilder.PROTOTYPE, 0);
/**
* Query that matches spans queries defined in <code>matchBuilder</code>
* whose end position is less than or equal to <code>end</code>.
@ -74,13 +80,60 @@ public class SpanFirstQueryBuilder extends AbstractQueryBuilder<SpanFirstQueryBu
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.field(SpanFirstQueryParser.MATCH_FIELD.getPreferredName());
builder.field(MATCH_FIELD.getPreferredName());
matchBuilder.toXContent(builder, params);
builder.field(SpanFirstQueryParser.END_FIELD.getPreferredName(), end);
builder.field(END_FIELD.getPreferredName(), end);
printBoostAndQueryName(builder);
builder.endObject();
}
public static SpanFirstQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
SpanQueryBuilder match = null;
Integer end = null;
String queryName = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, MATCH_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "spanFirst [match] must be of type span query");
}
match = (SpanQueryBuilder) query;
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_first] query does not support [" + currentFieldName + "]");
}
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, END_FIELD)) {
end = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_first] query does not support [" + currentFieldName + "]");
}
}
}
if (match == null) {
throw new ParsingException(parser.getTokenLocation(), "spanFirst must have [match] span query clause");
}
if (end == null) {
throw new ParsingException(parser.getTokenLocation(), "spanFirst must have [end] set for it");
}
SpanFirstQueryBuilder queryBuilder = new SpanFirstQueryBuilder(match, end);
queryBuilder.boost(boost).queryName(queryName);
return queryBuilder;
}
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
Query innerSpanQuery = matchBuilder.toQuery(context);

View File

@ -1,89 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for span_first query
*/
public class SpanFirstQueryParser implements QueryParser<SpanFirstQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(SpanFirstQueryBuilder.NAME);
public static final ParseField MATCH_FIELD = new ParseField("match");
public static final ParseField END_FIELD = new ParseField("end");
@Override
public SpanFirstQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
SpanQueryBuilder match = null;
Integer end = null;
String queryName = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, MATCH_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "spanFirst [match] must be of type span query");
}
match = (SpanQueryBuilder) query;
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_first] query does not support [" + currentFieldName + "]");
}
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, END_FIELD)) {
end = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_first] query does not support [" + currentFieldName + "]");
}
}
}
if (match == null) {
throw new ParsingException(parser.getTokenLocation(), "spanFirst must have [match] span query clause");
}
if (end == null) {
throw new ParsingException(parser.getTokenLocation(), "spanFirst must have [end] set for it");
}
SpanFirstQueryBuilder queryBuilder = new SpanFirstQueryBuilder(match, end);
queryBuilder.boost(boost).queryName(queryName);
return queryBuilder;
}
@Override
public SpanFirstQueryBuilder getBuilderPrototype() {
return SpanFirstQueryBuilder.PROTOTYPE;
}
}

View File

@ -22,9 +22,12 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.ArrayList;
@ -39,18 +42,23 @@ import java.util.Objects;
public class SpanNearQueryBuilder extends AbstractQueryBuilder<SpanNearQueryBuilder> implements SpanQueryBuilder<SpanNearQueryBuilder> {
public static final String NAME = "span_near";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final SpanNearQueryBuilder PROTOTYPE = new SpanNearQueryBuilder(SpanTermQueryBuilder.PROTOTYPE, 0);
/** Default for flag controlling whether matches are required to be in-order */
public static boolean DEFAULT_IN_ORDER = true;
private static final ParseField SLOP_FIELD = new ParseField("slop");
private static final ParseField COLLECT_PAYLOADS_FIELD = new ParseField("collect_payloads").withAllDeprecated("no longer supported");
private static final ParseField CLAUSES_FIELD = new ParseField("clauses");
private static final ParseField IN_ORDER_FIELD = new ParseField("in_order");
private final List<SpanQueryBuilder<?>> clauses = new ArrayList<>();
private final int slop;
private boolean inOrder = DEFAULT_IN_ORDER;
static final SpanNearQueryBuilder PROTOTYPE = new SpanNearQueryBuilder(SpanTermQueryBuilder.PROTOTYPE, 0);
/**
* @param initialClause an initial span query clause
* @param slop controls the maximum number of intervening unmatched positions permitted
@ -105,17 +113,81 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder<SpanNearQueryBuil
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.startArray(SpanNearQueryParser.CLAUSES_FIELD.getPreferredName());
builder.startArray(CLAUSES_FIELD.getPreferredName());
for (SpanQueryBuilder<?> clause : clauses) {
clause.toXContent(builder, params);
}
builder.endArray();
builder.field(SpanNearQueryParser.SLOP_FIELD.getPreferredName(), slop);
builder.field(SpanNearQueryParser.IN_ORDER_FIELD.getPreferredName(), inOrder);
builder.field(SLOP_FIELD.getPreferredName(), slop);
builder.field(IN_ORDER_FIELD.getPreferredName(), inOrder);
printBoostAndQueryName(builder);
builder.endObject();
}
public static SpanNearQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
Integer slop = null;
boolean inOrder = SpanNearQueryBuilder.DEFAULT_IN_ORDER;
String queryName = null;
List<SpanQueryBuilder> clauses = new ArrayList<>();
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 (parseContext.parseFieldMatcher().match(currentFieldName, CLAUSES_FIELD)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "spanNear [clauses] must be of type span query");
}
clauses.add((SpanQueryBuilder) query);
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_near] query does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, IN_ORDER_FIELD)) {
inOrder = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, COLLECT_PAYLOADS_FIELD)) {
// Deprecated in 3.0.0
} else if (parseContext.parseFieldMatcher().match(currentFieldName, SLOP_FIELD)) {
slop = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_near] query does not support [" + currentFieldName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_near] query does not support [" + currentFieldName + "]");
}
}
if (clauses.isEmpty()) {
throw new ParsingException(parser.getTokenLocation(), "span_near must include [clauses]");
}
if (slop == null) {
throw new ParsingException(parser.getTokenLocation(), "span_near must include [slop]");
}
SpanNearQueryBuilder queryBuilder = new SpanNearQueryBuilder(clauses.get(0), slop);
for (int i = 1; i < clauses.size(); i++) {
queryBuilder.clause(clauses.get(i));
}
queryBuilder.inOrder(inOrder);
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
return queryBuilder;
}
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
SpanQuery[] spanQueries = new SpanQuery[clauses.size()];

View File

@ -1,110 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Parser for span_near query
*/
public class SpanNearQueryParser implements QueryParser<SpanNearQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(SpanNearQueryBuilder.NAME);
public static final ParseField SLOP_FIELD = new ParseField("slop");
public static final ParseField COLLECT_PAYLOADS_FIELD = new ParseField("collect_payloads").withAllDeprecated("no longer supported");
public static final ParseField CLAUSES_FIELD = new ParseField("clauses");
public static final ParseField IN_ORDER_FIELD = new ParseField("in_order");
@Override
public SpanNearQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
Integer slop = null;
boolean inOrder = SpanNearQueryBuilder.DEFAULT_IN_ORDER;
String queryName = null;
List<SpanQueryBuilder> clauses = new ArrayList<>();
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 (parseContext.parseFieldMatcher().match(currentFieldName, CLAUSES_FIELD)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "spanNear [clauses] must be of type span query");
}
clauses.add((SpanQueryBuilder) query);
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_near] query does not support [" + currentFieldName + "]");
}
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, IN_ORDER_FIELD)) {
inOrder = parser.booleanValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, COLLECT_PAYLOADS_FIELD)) {
// Deprecated in 3.0.0
} else if (parseContext.parseFieldMatcher().match(currentFieldName, SLOP_FIELD)) {
slop = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_near] query does not support [" + currentFieldName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_near] query does not support [" + currentFieldName + "]");
}
}
if (clauses.isEmpty()) {
throw new ParsingException(parser.getTokenLocation(), "span_near must include [clauses]");
}
if (slop == null) {
throw new ParsingException(parser.getTokenLocation(), "span_near must include [slop]");
}
SpanNearQueryBuilder queryBuilder = new SpanNearQueryBuilder(clauses.get(0), slop);
for (int i = 1; i < clauses.size(); i++) {
queryBuilder.clause(clauses.get(i));
}
queryBuilder.inOrder(inOrder);
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
return queryBuilder;
}
@Override
public SpanNearQueryBuilder getBuilderPrototype() {
return SpanNearQueryBuilder.PROTOTYPE;
}
}

View File

@ -22,9 +22,12 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.spans.SpanNotQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
@ -32,12 +35,21 @@ import java.util.Objects;
public class SpanNotQueryBuilder extends AbstractQueryBuilder<SpanNotQueryBuilder> implements SpanQueryBuilder<SpanNotQueryBuilder> {
public static final String NAME = "span_not";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final SpanNotQueryBuilder PROTOTYPE = new SpanNotQueryBuilder(SpanTermQueryBuilder.PROTOTYPE,
SpanTermQueryBuilder.PROTOTYPE);
/** the default pre parameter size */
public static final int DEFAULT_PRE = 0;
/** the default post parameter size */
public static final int DEFAULT_POST = 0;
private static final ParseField POST_FIELD = new ParseField("post");
private static final ParseField PRE_FIELD = new ParseField("pre");
private static final ParseField DIST_FIELD = new ParseField("dist");
private static final ParseField EXCLUDE_FIELD = new ParseField("exclude");
private static final ParseField INCLUDE_FIELD = new ParseField("include");
private final SpanQueryBuilder include;
private final SpanQueryBuilder exclude;
@ -46,8 +58,6 @@ public class SpanNotQueryBuilder extends AbstractQueryBuilder<SpanNotQueryBuilde
private int post = DEFAULT_POST;
static final SpanNotQueryBuilder PROTOTYPE = new SpanNotQueryBuilder(SpanTermQueryBuilder.PROTOTYPE, SpanTermQueryBuilder.PROTOTYPE);
/**
* Construct a span query matching spans from <code>include</code> which
* have no overlap with spans from <code>exclude</code>.
@ -125,16 +135,92 @@ public class SpanNotQueryBuilder extends AbstractQueryBuilder<SpanNotQueryBuilde
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.field(SpanNotQueryParser.INCLUDE_FIELD.getPreferredName());
builder.field(INCLUDE_FIELD.getPreferredName());
include.toXContent(builder, params);
builder.field(SpanNotQueryParser.EXCLUDE_FIELD.getPreferredName());
builder.field(EXCLUDE_FIELD.getPreferredName());
exclude.toXContent(builder, params);
builder.field(SpanNotQueryParser.PRE_FIELD.getPreferredName(), pre);
builder.field(SpanNotQueryParser.POST_FIELD.getPreferredName(), post);
builder.field(PRE_FIELD.getPreferredName(), pre);
builder.field(POST_FIELD.getPreferredName(), post);
printBoostAndQueryName(builder);
builder.endObject();
}
public static SpanNotQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
SpanQueryBuilder include = null;
SpanQueryBuilder exclude = null;
Integer dist = null;
Integer pre = null;
Integer post = null;
String queryName = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, INCLUDE_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "spanNot [include] must be of type span query");
}
include = (SpanQueryBuilder) query;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, EXCLUDE_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "spanNot [exclude] must be of type span query");
}
exclude = (SpanQueryBuilder) query;
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_not] query does not support [" + currentFieldName + "]");
}
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, DIST_FIELD)) {
dist = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, PRE_FIELD)) {
pre = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, POST_FIELD)) {
post = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_not] query does not support [" + currentFieldName + "]");
}
}
}
if (include == null) {
throw new ParsingException(parser.getTokenLocation(), "spanNot must have [include] span query clause");
}
if (exclude == null) {
throw new ParsingException(parser.getTokenLocation(), "spanNot must have [exclude] span query clause");
}
if (dist != null && (pre != null || post != null)) {
throw new ParsingException(parser.getTokenLocation(), "spanNot can either use [dist] or [pre] & [post] (or none)");
}
SpanNotQueryBuilder spanNotQuery = new SpanNotQueryBuilder(include, exclude);
if (dist != null) {
spanNotQuery.dist(dist);
}
if (pre != null) {
spanNotQuery.pre(pre);
}
if (post != null) {
spanNotQuery.post(post);
}
spanNotQuery.boost(boost);
spanNotQuery.queryName(queryName);
return spanNotQuery;
}
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {

View File

@ -1,121 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for span_not query
*/
public class SpanNotQueryParser implements QueryParser<SpanNotQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(SpanNotQueryBuilder.NAME);
public static final ParseField POST_FIELD = new ParseField("post");
public static final ParseField PRE_FIELD = new ParseField("pre");
public static final ParseField DIST_FIELD = new ParseField("dist");
public static final ParseField EXCLUDE_FIELD = new ParseField("exclude");
public static final ParseField INCLUDE_FIELD = new ParseField("include");
@Override
public SpanNotQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
SpanQueryBuilder include = null;
SpanQueryBuilder exclude = null;
Integer dist = null;
Integer pre = null;
Integer post = null;
String queryName = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, INCLUDE_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "spanNot [include] must be of type span query");
}
include = (SpanQueryBuilder) query;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, EXCLUDE_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "spanNot [exclude] must be of type span query");
}
exclude = (SpanQueryBuilder) query;
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_not] query does not support [" + currentFieldName + "]");
}
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, DIST_FIELD)) {
dist = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, PRE_FIELD)) {
pre = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, POST_FIELD)) {
post = parser.intValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_not] query does not support [" + currentFieldName + "]");
}
}
}
if (include == null) {
throw new ParsingException(parser.getTokenLocation(), "spanNot must have [include] span query clause");
}
if (exclude == null) {
throw new ParsingException(parser.getTokenLocation(), "spanNot must have [exclude] span query clause");
}
if (dist != null && (pre != null || post != null)) {
throw new ParsingException(parser.getTokenLocation(), "spanNot can either use [dist] or [pre] & [post] (or none)");
}
SpanNotQueryBuilder spanNotQuery = new SpanNotQueryBuilder(include, exclude);
if (dist != null) {
spanNotQuery.dist(dist);
}
if (pre != null) {
spanNotQuery.pre(pre);
}
if (post != null) {
spanNotQuery.post(post);
}
spanNotQuery.boost(boost);
spanNotQuery.queryName(queryName);
return spanNotQuery;
}
@Override
public SpanNotQueryBuilder getBuilderPrototype() {
return SpanNotQueryBuilder.PROTOTYPE;
}
}

View File

@ -22,9 +22,12 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.spans.SpanOrQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.ArrayList;
@ -37,11 +40,13 @@ import java.util.Objects;
public class SpanOrQueryBuilder extends AbstractQueryBuilder<SpanOrQueryBuilder> implements SpanQueryBuilder<SpanOrQueryBuilder> {
public static final String NAME = "span_or";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final SpanOrQueryBuilder PROTOTYPE = new SpanOrQueryBuilder(SpanTermQueryBuilder.PROTOTYPE);
private static final ParseField CLAUSES_FIELD = new ParseField("clauses");
private final List<SpanQueryBuilder<?>> clauses = new ArrayList<>();
static final SpanOrQueryBuilder PROTOTYPE = new SpanOrQueryBuilder(SpanTermQueryBuilder.PROTOTYPE);
public SpanOrQueryBuilder(SpanQueryBuilder<?> initialClause) {
if (initialClause == null) {
throw new IllegalArgumentException("query must include at least one clause");
@ -67,7 +72,7 @@ public class SpanOrQueryBuilder extends AbstractQueryBuilder<SpanOrQueryBuilder>
@Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.startArray(SpanOrQueryParser.CLAUSES_FIELD.getPreferredName());
builder.startArray(CLAUSES_FIELD.getPreferredName());
for (SpanQueryBuilder<?> clause : clauses) {
clause.toXContent(builder, params);
}
@ -76,6 +81,55 @@ public class SpanOrQueryBuilder extends AbstractQueryBuilder<SpanOrQueryBuilder>
builder.endObject();
}
public static SpanOrQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
List<SpanQueryBuilder> clauses = new ArrayList<>();
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 (parseContext.parseFieldMatcher().match(currentFieldName, CLAUSES_FIELD)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "spanOr [clauses] must be of type span query");
}
clauses.add((SpanQueryBuilder) query);
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_or] query does not support [" + currentFieldName + "]");
}
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_or] query does not support [" + currentFieldName + "]");
}
}
}
if (clauses.isEmpty()) {
throw new ParsingException(parser.getTokenLocation(), "spanOr must include [clauses]");
}
SpanOrQueryBuilder queryBuilder = new SpanOrQueryBuilder(clauses.get(0));
for (int i = 1; i < clauses.size(); i++) {
queryBuilder.clause(clauses.get(i));
}
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
return queryBuilder;
}
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
SpanQuery[] spanQueries = new SpanQuery[clauses.size()];

View File

@ -1,93 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Parser for span_or query
*/
public class SpanOrQueryParser implements QueryParser<SpanOrQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(SpanOrQueryBuilder.NAME);
public static final ParseField CLAUSES_FIELD = new ParseField("clauses");
@Override
public SpanOrQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
List<SpanQueryBuilder> clauses = new ArrayList<>();
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 (parseContext.parseFieldMatcher().match(currentFieldName, CLAUSES_FIELD)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (!(query instanceof SpanQueryBuilder)) {
throw new ParsingException(parser.getTokenLocation(), "spanOr [clauses] must be of type span query");
}
clauses.add((SpanQueryBuilder) query);
}
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_or] query does not support [" + currentFieldName + "]");
}
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_or] query does not support [" + currentFieldName + "]");
}
}
}
if (clauses.isEmpty()) {
throw new ParsingException(parser.getTokenLocation(), "spanOr must include [clauses]");
}
SpanOrQueryBuilder queryBuilder = new SpanOrQueryBuilder(clauses.get(0));
for (int i = 1; i < clauses.size(); i++) {
queryBuilder.clause(clauses.get(i));
}
queryBuilder.boost(boost);
queryBuilder.queryName(queryName);
return queryBuilder;
}
@Override
public SpanOrQueryBuilder getBuilderPrototype() {
return SpanOrQueryBuilder.PROTOTYPE;
}
}

View File

@ -23,7 +23,10 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MappedFieldType;
import java.io.IOException;
@ -35,7 +38,10 @@ import java.io.IOException;
public class SpanTermQueryBuilder extends BaseTermQueryBuilder<SpanTermQueryBuilder> implements SpanQueryBuilder<SpanTermQueryBuilder> {
public static final String NAME = "span_term";
static final SpanTermQueryBuilder PROTOTYPE = new SpanTermQueryBuilder("name", "value");
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final SpanTermQueryBuilder PROTOTYPE = new SpanTermQueryBuilder("name", "value");
private static final ParseField TERM_FIELD = new ParseField("term");
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, String) */
public SpanTermQueryBuilder(String name, String value) {
@ -82,6 +88,58 @@ public class SpanTermQueryBuilder extends BaseTermQueryBuilder<SpanTermQueryBuil
return new SpanTermQuery(new Term(fieldName, valueBytes));
}
public static SpanTermQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException, ParsingException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.currentToken();
if (token == XContentParser.Token.START_OBJECT) {
token = parser.nextToken();
}
assert token == XContentParser.Token.FIELD_NAME;
String fieldName = parser.currentName();
Object value = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
token = parser.nextToken();
if (token == XContentParser.Token.START_OBJECT) {
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, TERM_FIELD)) {
value = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, BaseTermQueryBuilder.VALUE_FIELD)) {
value = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[span_term] query does not support [" + currentFieldName + "]");
}
}
}
parser.nextToken();
} else {
value = parser.objectBytes();
// move to the next token
parser.nextToken();
}
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for term query");
}
SpanTermQueryBuilder result = new SpanTermQueryBuilder(fieldName, value);
result.boost(boost).queryName(queryName);
return result;
}
@Override
protected SpanTermQueryBuilder createBuilder(String fieldName, Object value) {
return new SpanTermQueryBuilder(fieldName, value);

View File

@ -1,93 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for span_term query
*/
public class SpanTermQueryParser implements QueryParser<SpanTermQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(SpanTermQueryBuilder.NAME);
public static final ParseField TERM_FIELD = new ParseField("term");
@Override
public SpanTermQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException, ParsingException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.currentToken();
if (token == XContentParser.Token.START_OBJECT) {
token = parser.nextToken();
}
assert token == XContentParser.Token.FIELD_NAME;
String fieldName = parser.currentName();
Object value = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
token = parser.nextToken();
if (token == XContentParser.Token.START_OBJECT) {
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, TERM_FIELD)) {
value = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, BaseTermQueryBuilder.VALUE_FIELD)) {
value = parser.objectBytes();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[span_term] query does not support [" + currentFieldName + "]");
}
}
}
parser.nextToken();
} else {
value = parser.objectBytes();
// move to the next token
parser.nextToken();
}
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for term query");
}
SpanTermQueryBuilder result = new SpanTermQueryBuilder(fieldName, value);
result.boost(boost).queryName(queryName);
return result;
}
@Override
public SpanTermQueryBuilder getBuilderPrototype() {
return SpanTermQueryBuilder.PROTOTYPE;
}
}

View File

@ -22,9 +22,12 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanWithinQuery;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
@ -36,10 +39,15 @@ public class SpanWithinQueryBuilder extends AbstractQueryBuilder<SpanWithinQuery
implements SpanQueryBuilder<SpanWithinQueryBuilder> {
public static final String NAME = "span_within";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final SpanWithinQueryBuilder PROTOTYPE =
new SpanWithinQueryBuilder(SpanTermQueryBuilder.PROTOTYPE, SpanTermQueryBuilder.PROTOTYPE);
private static final ParseField BIG_FIELD = new ParseField("big");
private static final ParseField LITTLE_FIELD = new ParseField("little");
private final SpanQueryBuilder big;
private final SpanQueryBuilder little;
static final SpanWithinQueryBuilder PROTOTYPE =
new SpanWithinQueryBuilder(SpanTermQueryBuilder.PROTOTYPE, SpanTermQueryBuilder.PROTOTYPE);
/**
* Query that returns spans from <code>little</code> that are contained in a spans from <code>big</code>.
@ -75,10 +83,10 @@ public class SpanWithinQueryBuilder extends AbstractQueryBuilder<SpanWithinQuery
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.field(SpanWithinQueryParser.BIG_FIELD.getPreferredName());
builder.field(BIG_FIELD.getPreferredName());
big.toXContent(builder, params);
builder.field(SpanWithinQueryParser.LITTLE_FIELD.getPreferredName());
builder.field(LITTLE_FIELD.getPreferredName());
little.toXContent(builder, params);
printBoostAndQueryName(builder);
@ -86,6 +94,57 @@ public class SpanWithinQueryBuilder extends AbstractQueryBuilder<SpanWithinQuery
builder.endObject();
}
public static SpanWithinQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
SpanQueryBuilder big = null;
SpanQueryBuilder little = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, BIG_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (query instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "span_within [big] must be of type span query");
}
big = (SpanQueryBuilder) query;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LITTLE_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (query instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "span_within [little] must be of type span query");
}
little = (SpanQueryBuilder) query;
} else {
throw new ParsingException(parser.getTokenLocation(),
"[span_within] query does not support [" + currentFieldName + "]");
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_within] query does not support [" + currentFieldName + "]");
}
}
if (big == null) {
throw new ParsingException(parser.getTokenLocation(), "span_within must include [big]");
}
if (little == null) {
throw new ParsingException(parser.getTokenLocation(), "span_within must include [little]");
}
SpanWithinQueryBuilder query = new SpanWithinQueryBuilder(big, little);
query.boost(boost).queryName(queryName);
return query;
}
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
Query innerBig = big.toQuery(context);

View File

@ -1,93 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for span_within query
*/
public class SpanWithinQueryParser implements QueryParser<SpanWithinQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(SpanWithinQueryBuilder.NAME);
public static final ParseField BIG_FIELD = new ParseField("big");
public static final ParseField LITTLE_FIELD = new ParseField("little");
@Override
public SpanWithinQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
SpanQueryBuilder big = null;
SpanQueryBuilder little = null;
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_OBJECT) {
if (parseContext.parseFieldMatcher().match(currentFieldName, BIG_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (query instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "span_within [big] must be of type span query");
}
big = (SpanQueryBuilder) query;
} else if (parseContext.parseFieldMatcher().match(currentFieldName, LITTLE_FIELD)) {
QueryBuilder query = parseContext.parseInnerQueryBuilder();
if (query instanceof SpanQueryBuilder == false) {
throw new ParsingException(parser.getTokenLocation(), "span_within [little] must be of type span query");
}
little = (SpanQueryBuilder) query;
} else {
throw new ParsingException(parser.getTokenLocation(),
"[span_within] query does not support [" + currentFieldName + "]");
}
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(), "[span_within] query does not support [" + currentFieldName + "]");
}
}
if (big == null) {
throw new ParsingException(parser.getTokenLocation(), "span_within must include [big]");
}
if (little == null) {
throw new ParsingException(parser.getTokenLocation(), "span_within must include [little]");
}
SpanWithinQueryBuilder query = new SpanWithinQueryBuilder(big, little);
query.boost(boost).queryName(queryName);
return query;
}
@Override
public SpanWithinQueryBuilder getBuilderPrototype() {
return SpanWithinQueryBuilder.PROTOTYPE;
}
}

View File

@ -29,12 +29,15 @@ import org.apache.lucene.util.BytesRef;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.indices.TermsLookup;
@ -53,8 +56,8 @@ import java.util.stream.IntStream;
public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
public static final String NAME = "terms";
static final TermsQueryBuilder PROTOTYPE = new TermsQueryBuilder("field", "value");
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME, "in");
public static final TermsQueryBuilder PROTOTYPE = new TermsQueryBuilder("field", "value");
private final String fieldName;
private final List<Object> values;
@ -219,6 +222,74 @@ public class TermsQueryBuilder extends AbstractQueryBuilder<TermsQueryBuilder> {
builder.endObject();
}
public static TermsQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = null;
List<Object> values = null;
TermsLookup termsLookup = null;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
XContentParser.Token token;
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (parseContext.isDeprecatedSetting(currentFieldName)) {
// skip
} else if (token == XContentParser.Token.START_ARRAY) {
if (fieldName != null) {
throw new ParsingException(parser.getTokenLocation(),
"[" + TermsQueryBuilder.NAME + "] query does not support multiple fields");
}
fieldName = currentFieldName;
values = parseValues(parser);
} else if (token == XContentParser.Token.START_OBJECT) {
if (fieldName != null) {
throw new ParsingException(parser.getTokenLocation(),
"[" + TermsQueryBuilder.NAME + "] query does not support more than one field. "
+ "Already got: [" + fieldName + "] but also found [" + currentFieldName +"]");
}
fieldName = currentFieldName;
termsLookup = TermsLookup.parseTermsLookup(parser);
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[" + TermsQueryBuilder.NAME + "] query does not support [" + currentFieldName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(),
"[" + TermsQueryBuilder.NAME + "] unknown token [" + token + "] after [" + currentFieldName + "]");
}
}
if (fieldName == null) {
throw new ParsingException(parser.getTokenLocation(), "[" + TermsQueryBuilder.NAME + "] query requires a field name, " +
"followed by array of terms or a document lookup specification");
}
return new TermsQueryBuilder(fieldName, values, termsLookup)
.boost(boost)
.queryName(queryName);
}
private static List<Object> parseValues(XContentParser parser) throws IOException {
List<Object> values = new ArrayList<>();
while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
Object value = parser.objectBytes();
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for terms query");
}
values.add(value);
}
return values;
}
@Override
public String getWriteableName() {
return NAME;

View File

@ -1,116 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.indices.TermsLookup;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Parser for terms query and terms lookup.
*
* Filters documents that have fields that match any of the provided terms (not analyzed)
*
* It also supports a terms lookup mechanism which can be used to fetch the term values from
* a document in an index.
*/
public class TermsQueryParser implements QueryParser {
public static final ParseField QUERY_NAME_FIELD = new ParseField(TermsQueryBuilder.NAME, "in");
@Override
public QueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
String fieldName = null;
List<Object> values = null;
TermsLookup termsLookup = null;
String queryName = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
XContentParser.Token token;
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (parseContext.isDeprecatedSetting(currentFieldName)) {
// skip
} else if (token == XContentParser.Token.START_ARRAY) {
if (fieldName != null) {
throw new ParsingException(parser.getTokenLocation(),
"[" + TermsQueryBuilder.NAME + "] query does not support multiple fields");
}
fieldName = currentFieldName;
values = parseValues(parser);
} else if (token == XContentParser.Token.START_OBJECT) {
if (fieldName != null) {
throw new ParsingException(parser.getTokenLocation(),
"[" + TermsQueryBuilder.NAME + "] query does not support more than one field. "
+ "Already got: [" + fieldName + "] but also found [" + currentFieldName +"]");
}
fieldName = currentFieldName;
termsLookup = TermsLookup.parseTermsLookup(parser);
} else if (token.isValue()) {
if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[" + TermsQueryBuilder.NAME + "] query does not support [" + currentFieldName + "]");
}
} else {
throw new ParsingException(parser.getTokenLocation(),
"[" + TermsQueryBuilder.NAME + "] unknown token [" + token + "] after [" + currentFieldName + "]");
}
}
if (fieldName == null) {
throw new ParsingException(parser.getTokenLocation(), "[" + TermsQueryBuilder.NAME + "] query requires a field name, " +
"followed by array of terms or a document lookup specification");
}
return new TermsQueryBuilder(fieldName, values, termsLookup)
.boost(boost)
.queryName(queryName);
}
private static List<Object> parseValues(XContentParser parser) throws IOException {
List<Object> values = new ArrayList<>();
while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
Object value = parser.objectBytes();
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for terms query");
}
values.add(value);
}
return values;
}
@Override
public TermsQueryBuilder getBuilderPrototype() {
return TermsQueryBuilder.PROTOTYPE;
}
}

View File

@ -24,10 +24,13 @@ import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.query.support.QueryParsers;
@ -46,6 +49,12 @@ public class WildcardQueryBuilder extends AbstractQueryBuilder<WildcardQueryBuil
implements MultiTermQueryBuilder<WildcardQueryBuilder> {
public static final String NAME = "wildcard";
public static final ParseField QUERY_NAME_FIELD = new ParseField(NAME);
public static final WildcardQueryBuilder PROTOTYPE = new WildcardQueryBuilder("field", "value");
private static final ParseField WILDCARD_FIELD = new ParseField("wildcard");
private static final ParseField VALUE_FIELD = new ParseField("value");
private static final ParseField REWRITE_FIELD = new ParseField("rewrite");
private final String fieldName;
@ -53,8 +62,6 @@ public class WildcardQueryBuilder extends AbstractQueryBuilder<WildcardQueryBuil
private String rewrite;
static final WildcardQueryBuilder PROTOTYPE = new WildcardQueryBuilder("field", "value");
/**
* Implements the wildcard search query. Supported wildcards are <tt>*</tt>, which
* matches any character sequence (including the empty one), and <tt>?</tt>,
@ -103,15 +110,66 @@ public class WildcardQueryBuilder extends AbstractQueryBuilder<WildcardQueryBuil
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(NAME);
builder.startObject(fieldName);
builder.field(WildcardQueryParser.WILDCARD_FIELD.getPreferredName(), value);
builder.field(WILDCARD_FIELD.getPreferredName(), value);
if (rewrite != null) {
builder.field(WildcardQueryParser.REWRITE_FIELD.getPreferredName(), rewrite);
builder.field(REWRITE_FIELD.getPreferredName(), rewrite);
}
printBoostAndQueryName(builder);
builder.endObject();
builder.endObject();
}
public static WildcardQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.FIELD_NAME) {
throw new ParsingException(parser.getTokenLocation(), "[wildcard] query malformed, no field");
}
String fieldName = parser.currentName();
String rewrite = null;
String value = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
token = parser.nextToken();
if (token == XContentParser.Token.START_OBJECT) {
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, WILDCARD_FIELD)) {
value = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, VALUE_FIELD)) {
value = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, REWRITE_FIELD)) {
rewrite = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[wildcard] query does not support [" + currentFieldName + "]");
}
}
}
parser.nextToken();
} else {
value = parser.text();
parser.nextToken();
}
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for prefix query");
}
return new WildcardQueryBuilder(fieldName, value)
.rewrite(rewrite)
.boost(boost)
.queryName(queryName);
}
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
String indexFieldName;

View File

@ -1,94 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Parser for wildcard query
*/
public class WildcardQueryParser implements QueryParser<WildcardQueryBuilder> {
public static final ParseField QUERY_NAME_FIELD = new ParseField(WildcardQueryBuilder.NAME);
public static final ParseField WILDCARD_FIELD = new ParseField("wildcard");
public static final ParseField VALUE_FIELD = new ParseField("value");
public static final ParseField REWRITE_FIELD = new ParseField("rewrite");
@Override
public WildcardQueryBuilder fromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.FIELD_NAME) {
throw new ParsingException(parser.getTokenLocation(), "[wildcard] query malformed, no field");
}
String fieldName = parser.currentName();
String rewrite = null;
String value = null;
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
String queryName = null;
token = parser.nextToken();
if (token == XContentParser.Token.START_OBJECT) {
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if (parseContext.parseFieldMatcher().match(currentFieldName, WILDCARD_FIELD)) {
value = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, VALUE_FIELD)) {
value = parser.text();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, REWRITE_FIELD)) {
rewrite = parser.textOrNull();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.NAME_FIELD)) {
queryName = parser.text();
} else {
throw new ParsingException(parser.getTokenLocation(),
"[wildcard] query does not support [" + currentFieldName + "]");
}
}
}
parser.nextToken();
} else {
value = parser.text();
parser.nextToken();
}
if (value == null) {
throw new ParsingException(parser.getTokenLocation(), "No value specified for prefix query");
}
return new WildcardQueryBuilder(fieldName, value)
.rewrite(rewrite)
.boost(boost)
.queryName(queryName);
}
@Override
public WildcardQueryBuilder getBuilderPrototype() {
return WildcardQueryBuilder.PROTOTYPE;
}
}

View File

@ -33,14 +33,14 @@ import org.elasticsearch.common.lucene.search.function.ScoreFunction;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.percolator.PercolatorHighlightSubFetchPhase;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.BoostingQueryParser;
import org.elasticsearch.index.query.BoostingQueryBuilder;
import org.elasticsearch.index.query.CommonTermsQueryBuilder;
import org.elasticsearch.index.query.ConstantScoreQueryParser;
import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
import org.elasticsearch.index.query.DisMaxQueryBuilder;
import org.elasticsearch.index.query.EmptyQueryBuilder;
import org.elasticsearch.index.query.ExistsQueryBuilder;
import org.elasticsearch.index.query.FieldMaskingSpanQueryParser;
import org.elasticsearch.index.query.FuzzyQueryParser;
import org.elasticsearch.index.query.FieldMaskingSpanQueryBuilder;
import org.elasticsearch.index.query.FuzzyQueryBuilder;
import org.elasticsearch.index.query.GeoBoundingBoxQueryBuilder;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.index.query.GeoDistanceRangeQueryBuilder;
@ -51,38 +51,37 @@ import org.elasticsearch.index.query.HasChildQueryBuilder;
import org.elasticsearch.index.query.HasParentQueryBuilder;
import org.elasticsearch.index.query.IdsQueryBuilder;
import org.elasticsearch.index.query.IndicesQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryParser;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.MatchNoneQueryBuilder;
import org.elasticsearch.index.query.MatchPhrasePrefixQueryBuilder;
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.MoreLikeThisQueryParser;
import org.elasticsearch.index.query.MoreLikeThisQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.ParentIdQueryBuilder;
import org.elasticsearch.index.query.PercolatorQueryBuilder;
import org.elasticsearch.index.query.PrefixQueryParser;
import org.elasticsearch.index.query.PrefixQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryParser;
import org.elasticsearch.index.query.QueryStringQueryParser;
import org.elasticsearch.index.query.RangeQueryParser;
import org.elasticsearch.index.query.RegexpQueryParser;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.RegexpQueryBuilder;
import org.elasticsearch.index.query.ScriptQueryBuilder;
import org.elasticsearch.index.query.SimpleQueryStringBuilder;
import org.elasticsearch.index.query.SpanContainingQueryParser;
import org.elasticsearch.index.query.SpanFirstQueryParser;
import org.elasticsearch.index.query.SpanContainingQueryBuilder;
import org.elasticsearch.index.query.SpanFirstQueryBuilder;
import org.elasticsearch.index.query.SpanMultiTermQueryBuilder;
import org.elasticsearch.index.query.SpanNearQueryParser;
import org.elasticsearch.index.query.SpanNotQueryParser;
import org.elasticsearch.index.query.SpanOrQueryParser;
import org.elasticsearch.index.query.SpanTermQueryParser;
import org.elasticsearch.index.query.SpanWithinQueryParser;
import org.elasticsearch.index.query.SpanNearQueryBuilder;
import org.elasticsearch.index.query.SpanNotQueryBuilder;
import org.elasticsearch.index.query.SpanOrQueryBuilder;
import org.elasticsearch.index.query.SpanTermQueryBuilder;
import org.elasticsearch.index.query.SpanWithinQueryBuilder;
import org.elasticsearch.index.query.TemplateQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.query.TermsQueryParser;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.index.query.TypeQueryBuilder;
import org.elasticsearch.index.query.WildcardQueryParser;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.elasticsearch.index.query.WrapperQueryBuilder;
import org.elasticsearch.index.query.functionscore.ExponentialDecayFunctionBuilder;
import org.elasticsearch.index.query.functionscore.FieldValueFactorFunctionBuilder;
@ -561,29 +560,36 @@ public class SearchModule extends AbstractModule {
HasParentQueryBuilder.QUERY_NAME_FIELD);
registerQuery(DisMaxQueryBuilder.PROTOTYPE::readFrom, DisMaxQueryBuilder::fromXContent, DisMaxQueryBuilder.QUERY_NAME_FIELD);
registerQuery(IdsQueryBuilder.PROTOTYPE::readFrom, IdsQueryBuilder::fromXContent, IdsQueryBuilder.QUERY_NAME_FIELD);
registerQueryParser(new MatchAllQueryParser(), MatchAllQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new QueryStringQueryParser(), QueryStringQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new BoostingQueryParser(), BoostingQueryParser.QUERY_NAME_FIELD);
registerQuery(MatchAllQueryBuilder.PROTOTYPE::readFrom, MatchAllQueryBuilder::fromXContent, MatchAllQueryBuilder.QUERY_NAME_FIELD);
registerQuery(QueryStringQueryBuilder.PROTOTYPE::readFrom, QueryStringQueryBuilder::fromXContent,
QueryStringQueryBuilder.QUERY_NAME_FIELD);
registerQuery(BoostingQueryBuilder.PROTOTYPE::readFrom, BoostingQueryBuilder::fromXContent, BoostingQueryBuilder.QUERY_NAME_FIELD);
BooleanQuery.setMaxClauseCount(settings.getAsInt("index.query.bool.max_clause_count",
settings.getAsInt("indices.query.bool.max_clause_count", BooleanQuery.getMaxClauseCount())));
registerQuery(BoolQueryBuilder.PROTOTYPE::readFrom, BoolQueryBuilder::fromXContent, BoolQueryBuilder.QUERY_NAME_FIELD);
registerQuery(TermQueryBuilder.PROTOTYPE::readFrom, TermQueryBuilder::fromXContent, TermQueryBuilder.QUERY_NAME_FIELD);
registerQueryParser(new TermsQueryParser(), TermsQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new FuzzyQueryParser(), FuzzyQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new RegexpQueryParser(), RegexpQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new RangeQueryParser(), RangeQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new PrefixQueryParser(), PrefixQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new WildcardQueryParser(), WildcardQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new ConstantScoreQueryParser(), ConstantScoreQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new SpanTermQueryParser(), SpanTermQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new SpanNotQueryParser(), SpanNotQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new SpanWithinQueryParser(), SpanWithinQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new SpanContainingQueryParser(), SpanContainingQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new FieldMaskingSpanQueryParser(), FieldMaskingSpanQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new SpanFirstQueryParser(), SpanFirstQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new SpanNearQueryParser(), SpanNearQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new SpanOrQueryParser(), SpanOrQueryParser.QUERY_NAME_FIELD);
registerQueryParser(new MoreLikeThisQueryParser(), MoreLikeThisQueryParser.QUERY_NAME_FIELD);
registerQuery(TermsQueryBuilder.PROTOTYPE::readFrom, TermsQueryBuilder::fromXContent, TermsQueryBuilder.QUERY_NAME_FIELD);
registerQuery(FuzzyQueryBuilder.PROTOTYPE::readFrom, FuzzyQueryBuilder::fromXContent, FuzzyQueryBuilder.QUERY_NAME_FIELD);
registerQuery(RegexpQueryBuilder.PROTOTYPE::readFrom, RegexpQueryBuilder::fromXContent, RegexpQueryBuilder.QUERY_NAME_FIELD);
registerQuery(RangeQueryBuilder.PROTOTYPE::readFrom, RangeQueryBuilder::fromXContent, RangeQueryBuilder.QUERY_NAME_FIELD);
registerQuery(PrefixQueryBuilder.PROTOTYPE::readFrom, PrefixQueryBuilder::fromXContent, PrefixQueryBuilder.QUERY_NAME_FIELD);
registerQuery(WildcardQueryBuilder.PROTOTYPE::readFrom, WildcardQueryBuilder::fromXContent, WildcardQueryBuilder.QUERY_NAME_FIELD);
registerQuery(ConstantScoreQueryBuilder.PROTOTYPE::readFrom, ConstantScoreQueryBuilder::fromXContent,
ConstantScoreQueryBuilder.QUERY_NAME_FIELD);
registerQuery(SpanTermQueryBuilder.PROTOTYPE::readFrom, SpanTermQueryBuilder::fromXContent, SpanTermQueryBuilder.QUERY_NAME_FIELD);
registerQuery(SpanNotQueryBuilder.PROTOTYPE::readFrom, SpanNotQueryBuilder::fromXContent, SpanNotQueryBuilder.QUERY_NAME_FIELD);
registerQuery(SpanWithinQueryBuilder.PROTOTYPE::readFrom, SpanWithinQueryBuilder::fromXContent,
SpanWithinQueryBuilder.QUERY_NAME_FIELD);
registerQuery(SpanContainingQueryBuilder.PROTOTYPE::readFrom, SpanContainingQueryBuilder::fromXContent,
SpanContainingQueryBuilder.QUERY_NAME_FIELD);
registerQuery(FieldMaskingSpanQueryBuilder.PROTOTYPE::readFrom, FieldMaskingSpanQueryBuilder::fromXContent,
FieldMaskingSpanQueryBuilder.QUERY_NAME_FIELD);
registerQuery(SpanFirstQueryBuilder.PROTOTYPE::readFrom, SpanFirstQueryBuilder::fromXContent,
SpanFirstQueryBuilder.QUERY_NAME_FIELD);
registerQuery(SpanNearQueryBuilder.PROTOTYPE::readFrom, SpanNearQueryBuilder::fromXContent, SpanNearQueryBuilder.QUERY_NAME_FIELD);
registerQuery(SpanOrQueryBuilder.PROTOTYPE::readFrom, SpanOrQueryBuilder::fromXContent, SpanOrQueryBuilder.QUERY_NAME_FIELD);
registerQuery(MoreLikeThisQueryBuilder.PROTOTYPE::readFrom, MoreLikeThisQueryBuilder::fromXContent,
MoreLikeThisQueryBuilder.QUERY_NAME_FIELD);
registerQuery(WrapperQueryBuilder.PROTOTYPE::readFrom, WrapperQueryBuilder::fromXContent, WrapperQueryBuilder.QUERY_NAME_FIELD);
registerQuery(IndicesQueryBuilder.PROTOTYPE::readFrom, IndicesQueryBuilder::fromXContent, IndicesQueryBuilder.QUERY_NAME_FIELD);
registerQuery(CommonTermsQueryBuilder.PROTOTYPE::readFrom, CommonTermsQueryBuilder::fromXContent,

View File

@ -28,7 +28,7 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryParser;
import org.elasticsearch.index.query.QueryParser;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.rest.action.search.RestMultiSearchAction;
import org.elasticsearch.script.ScriptService;
@ -36,19 +36,16 @@ import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.StreamsUtils;
import java.io.IOException;
import java.util.Collections;
import static java.util.Collections.singletonMap;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
public class MultiSearchRequestTests extends ESTestCase {
public void testSimpleAdd() throws Exception {
IndicesQueriesRegistry registry = new IndicesQueriesRegistry(Settings.EMPTY,
Collections.singletonMap(MatchAllQueryBuilder.NAME,
new Tuple<>(MatchAllQueryParser.QUERY_NAME_FIELD, new MatchAllQueryParser())));
byte[] data = StreamsUtils.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch1.json");
MultiSearchRequest request = RestMultiSearchAction.parseRequest(new MultiSearchRequest(), new BytesArray(data), false, null, null,
null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry, ParseFieldMatcher.EMPTY, null, null);
null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry(), ParseFieldMatcher.EMPTY, null, null);
assertThat(request.requests().size(), equalTo(8));
assertThat(request.requests().get(0).indices()[0], equalTo("test"));
assertThat(request.requests().get(0).indicesOptions(), equalTo(IndicesOptions.fromOptions(true, true, true, true, IndicesOptions.strictExpandOpenAndForbidClosed())));
@ -72,12 +69,9 @@ public class MultiSearchRequestTests extends ESTestCase {
}
public void testSimpleAdd2() throws Exception {
IndicesQueriesRegistry registry = new IndicesQueriesRegistry(Settings.EMPTY,
Collections.singletonMap(MatchAllQueryBuilder.NAME,
new Tuple<>(MatchAllQueryParser.QUERY_NAME_FIELD, new MatchAllQueryParser())));
byte[] data = StreamsUtils.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch2.json");
MultiSearchRequest request = RestMultiSearchAction.parseRequest(new MultiSearchRequest(), new BytesArray(data), false, null, null,
null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry, ParseFieldMatcher.EMPTY, null, null);
null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry(), ParseFieldMatcher.EMPTY, null, null);
assertThat(request.requests().size(), equalTo(5));
assertThat(request.requests().get(0).indices()[0], equalTo("test"));
assertThat(request.requests().get(0).types().length, equalTo(0));
@ -93,12 +87,9 @@ public class MultiSearchRequestTests extends ESTestCase {
}
public void testSimpleAdd3() throws Exception {
IndicesQueriesRegistry registry = new IndicesQueriesRegistry(Settings.EMPTY,
Collections.singletonMap(MatchAllQueryBuilder.NAME,
new Tuple<>(MatchAllQueryParser.QUERY_NAME_FIELD, new MatchAllQueryParser())));
byte[] data = StreamsUtils.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch3.json");
MultiSearchRequest request = RestMultiSearchAction.parseRequest(new MultiSearchRequest(), new BytesArray(data), false, null, null,
null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry, ParseFieldMatcher.EMPTY, null, null);
null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry(), ParseFieldMatcher.EMPTY, null, null);
assertThat(request.requests().size(), equalTo(4));
assertThat(request.requests().get(0).indices()[0], equalTo("test0"));
assertThat(request.requests().get(0).indices()[1], equalTo("test1"));
@ -115,12 +106,9 @@ public class MultiSearchRequestTests extends ESTestCase {
}
public void testSimpleAdd4() throws Exception {
IndicesQueriesRegistry registry = new IndicesQueriesRegistry(Settings.EMPTY,
Collections.singletonMap(MatchAllQueryBuilder.NAME,
new Tuple<>(MatchAllQueryParser.QUERY_NAME_FIELD, new MatchAllQueryParser())));
byte[] data = StreamsUtils.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch4.json");
MultiSearchRequest request = RestMultiSearchAction.parseRequest(new MultiSearchRequest(), new BytesArray(data), false, null, null,
null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry, ParseFieldMatcher.EMPTY, null, null);
null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry(), ParseFieldMatcher.EMPTY, null, null);
assertThat(request.requests().size(), equalTo(3));
assertThat(request.requests().get(0).indices()[0], equalTo("test0"));
assertThat(request.requests().get(0).indices()[1], equalTo("test1"));
@ -139,12 +127,9 @@ public class MultiSearchRequestTests extends ESTestCase {
}
public void testSimpleAdd5() throws Exception {
IndicesQueriesRegistry registry = new IndicesQueriesRegistry(Settings.EMPTY,
Collections.singletonMap(MatchAllQueryBuilder.NAME,
new Tuple<>(MatchAllQueryParser.QUERY_NAME_FIELD, new MatchAllQueryParser())));
byte[] data = StreamsUtils.copyToBytesFromClasspath("/org/elasticsearch/action/search/simple-msearch5.json");
MultiSearchRequest request = RestMultiSearchAction.parseRequest(new MultiSearchRequest(), new BytesArray(data), true, null, null,
null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry, ParseFieldMatcher.EMPTY, null, null);
null, null, IndicesOptions.strictExpandOpenAndForbidClosed(), true, registry(), ParseFieldMatcher.EMPTY, null, null);
assertThat(request.requests().size(), equalTo(3));
assertThat(request.requests().get(0).indices()[0], equalTo("test0"));
assertThat(request.requests().get(0).indices()[1], equalTo("test1"));
@ -181,4 +166,10 @@ public class MultiSearchRequestTests extends ESTestCase {
assertEquals("\"responses\"[{\"error\":{\"root_cause\":[{\"type\":\"illegal_state_exception\",\"reason\":\"foobar\"}],\"type\":\"illegal_state_exception\",\"reason\":\"foobar\"}},{\"error\":{\"root_cause\":[{\"type\":\"illegal_state_exception\",\"reason\":\"baaaaaazzzz\"}],\"type\":\"illegal_state_exception\",\"reason\":\"baaaaaazzzz\"}}]",
builder.string());
}
private IndicesQueriesRegistry registry() {
QueryParser<MatchAllQueryBuilder> parser = MatchAllQueryBuilder::fromXContent;
return new IndicesQueriesRegistry(Settings.EMPTY,
singletonMap(MatchAllQueryBuilder.NAME, new Tuple<>(MatchAllQueryBuilder.QUERY_NAME_FIELD, parser)));
}
}

View File

@ -66,7 +66,6 @@ import org.elasticsearch.index.query.QueryParser;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.elasticsearch.index.query.WildcardQueryParser;
import org.elasticsearch.index.shard.IndexShard;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.similarity.SimilarityService;
@ -105,7 +104,8 @@ public class PercolatorQueryCacheTests extends ESTestCase {
Map<String, Tuple<ParseField, QueryParser<?>>> queryParsers = new HashMap<>();
QueryParser<TermQueryBuilder> termParser = TermQueryBuilder::fromXContent;
queryParsers.put(TermQueryBuilder.NAME, new Tuple<>(TermQueryBuilder.QUERY_NAME_FIELD, termParser));
queryParsers.put(WildcardQueryBuilder.NAME, new Tuple<>(WildcardQueryParser.QUERY_NAME_FIELD, new WildcardQueryParser()));
QueryParser<WildcardQueryBuilder> wildcardParser = WildcardQueryBuilder::fromXContent;
queryParsers.put(WildcardQueryBuilder.NAME, new Tuple<>(WildcardQueryBuilder.QUERY_NAME_FIELD, wildcardParser));
QueryParser<BoolQueryBuilder> boolQueryParser = BoolQueryBuilder::fromXContent;
queryParsers.put(BoolQueryBuilder.NAME, new Tuple<>(BoolQueryBuilder.QUERY_NAME_FIELD, boolQueryParser));
IndicesQueriesRegistry indicesQueriesRegistry = new IndicesQueriesRegistry(settings, queryParsers);

View File

@ -27,14 +27,14 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryParser;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryParser;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.test.ESTestCase;
import org.hamcrest.Matchers;
@ -57,10 +57,11 @@ public class SearchAfterBuilderTests extends ESTestCase {
@BeforeClass
public static void init() {
namedWriteableRegistry = new NamedWriteableRegistry();
QueryParser<MatchAllQueryBuilder> parser = MatchAllQueryBuilder::fromXContent;
indicesQueriesRegistry = new IndicesQueriesRegistry(
Settings.settingsBuilder().build(),
Collections.singletonMap(
MatchAllQueryBuilder.NAME, new Tuple<>(MatchAllQueryParser.QUERY_NAME_FIELD, new MatchAllQueryParser())));
MatchAllQueryBuilder.NAME, new Tuple<>(MatchAllQueryBuilder.QUERY_NAME_FIELD, parser)));
}
@AfterClass