mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-07 13:38:49 +00:00
Refactors SpanTermQueryBuilder.
This attempts to do to SpanTermQueryBuilder what has already been changed for TermQueryBuilder. The commit tries to avoid code duplication where possible by pulling what is the same for both QueryBuilders and tests into separate classes. Relates to #10217
This commit is contained in:
parent
d7884b662c
commit
65f2641695
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* 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.apache.lucene.util.BytesRef;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Streamable;
|
||||
import org.elasticsearch.common.lucene.BytesRefs;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class BaseTermQueryBuilder<QB extends BoostableQueryBuilder<QB>> extends QueryBuilder implements Streamable, BoostableQueryBuilder<QB> {
|
||||
|
||||
/** Name of field to match against. */
|
||||
protected String fieldName;
|
||||
|
||||
/** Value to find matches for. */
|
||||
protected Object value;
|
||||
|
||||
/** Query boost. */
|
||||
protected float boost = 1.0f;
|
||||
|
||||
/** Name of the query. */
|
||||
protected String queryName;
|
||||
|
||||
/**
|
||||
* Constructs a new base term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
public BaseTermQueryBuilder(String fieldName, String value) {
|
||||
this(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new base term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
public BaseTermQueryBuilder(String fieldName, int value) {
|
||||
this(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new base term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
public BaseTermQueryBuilder(String fieldName, long value) {
|
||||
this(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new base term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
public BaseTermQueryBuilder(String fieldName, float value) {
|
||||
this(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new base term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
public BaseTermQueryBuilder(String fieldName, double value) {
|
||||
this(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new base term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
public BaseTermQueryBuilder(String fieldName, boolean value) {
|
||||
this(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new base term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
public BaseTermQueryBuilder(String fieldName, Object value) {
|
||||
this.fieldName = fieldName;
|
||||
if (value instanceof String) {
|
||||
this.value = BytesRefs.toBytesRef(value);
|
||||
} else {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
BaseTermQueryBuilder() {
|
||||
// for serialization only
|
||||
}
|
||||
|
||||
/** Returns the field name used in this query. */
|
||||
public String fieldName() {
|
||||
return this.fieldName;
|
||||
}
|
||||
|
||||
/** Returns the value used in this query. */
|
||||
public Object value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/** Returns the query name for the query. */
|
||||
public String queryName() {
|
||||
return this.queryName;
|
||||
}
|
||||
/**
|
||||
* Sets the query name for the query.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public QB queryName(String queryName) {
|
||||
this.queryName = queryName;
|
||||
return (QB) this;
|
||||
}
|
||||
|
||||
/** Returns the boost for this query. */
|
||||
public float boost() {
|
||||
return this.boost;
|
||||
}
|
||||
/**
|
||||
* Sets the boost for this query. Documents matching this query will (in addition to the normal
|
||||
* weightings) have their score multiplied by the boost provided.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public QB boost(float boost) {
|
||||
this.boost = boost;
|
||||
return (QB) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(parserName());
|
||||
Object valueToWrite = value;
|
||||
if (value instanceof BytesRef) {
|
||||
valueToWrite = ((BytesRef) value).utf8ToString();
|
||||
}
|
||||
|
||||
if (boost == 1.0f && queryName == null) {
|
||||
builder.field(fieldName, valueToWrite);
|
||||
} else {
|
||||
builder.startObject(fieldName);
|
||||
builder.field("value", valueToWrite);
|
||||
if (boost != 1.0f) {
|
||||
builder.field("boost", boost);
|
||||
}
|
||||
if (queryName != null) {
|
||||
builder.field("_name", queryName);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
/** Returns a {@link QueryValidationException} if fieldName is null or empty, or if value is null. */
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
QueryValidationException validationException = null;
|
||||
if (fieldName == null || fieldName.isEmpty()) {
|
||||
validationException = QueryValidationException.addValidationError("field name cannot be null or empty.", validationException);
|
||||
}
|
||||
if (value == null) {
|
||||
validationException = QueryValidationException.addValidationError("value cannot be null.", validationException);
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getClass(), fieldName, value, boost, queryName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
@SuppressWarnings("rawtypes")
|
||||
BaseTermQueryBuilder other = (BaseTermQueryBuilder) obj;
|
||||
return Objects.equals(fieldName, other.fieldName) &&
|
||||
Objects.equals(value, other.value) &&
|
||||
Objects.equals(boost, other.boost) &&
|
||||
Objects.equals(queryName, other.queryName);
|
||||
}
|
||||
|
||||
/** Read the given parameters. */
|
||||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
fieldName = in.readString();
|
||||
value = in.readGenericValue();
|
||||
boost = in.readFloat();
|
||||
queryName = in.readOptionalString();
|
||||
}
|
||||
|
||||
/** Writes the given parameters. */
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeString(fieldName);
|
||||
out.writeGenericValue(value);
|
||||
out.writeFloat(boost);
|
||||
out.writeOptionalString(queryName);
|
||||
}
|
||||
}
|
@ -19,6 +19,6 @@
|
||||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
public abstract class SpanQueryBuilder extends QueryBuilder {
|
||||
public interface SpanQueryBuilder {
|
||||
|
||||
}
|
||||
|
@ -19,80 +19,71 @@
|
||||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SpanTermQueryBuilder extends SpanQueryBuilder implements BoostableQueryBuilder<SpanTermQueryBuilder> {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final Object value;
|
||||
|
||||
private float boost = -1;
|
||||
|
||||
private String queryName;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.spans.SpanTermQuery;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.elasticsearch.common.lucene.BytesRefs;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
|
||||
/**
|
||||
* A Span Query that matches documents containing a term.
|
||||
* @see SpanTermQuery
|
||||
*/
|
||||
public class SpanTermQueryBuilder extends BaseTermQueryBuilder<SpanTermQueryBuilder> implements SpanQueryBuilder {
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, String) */
|
||||
public SpanTermQueryBuilder(String name, String value) {
|
||||
this(name, (Object) value);
|
||||
super(name, (Object) value);
|
||||
}
|
||||
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, int) */
|
||||
public SpanTermQueryBuilder(String name, int value) {
|
||||
this(name, (Object) value);
|
||||
super(name, (Object) value);
|
||||
}
|
||||
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, long) */
|
||||
public SpanTermQueryBuilder(String name, long value) {
|
||||
this(name, (Object) value);
|
||||
super(name, (Object) value);
|
||||
}
|
||||
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, float) */
|
||||
public SpanTermQueryBuilder(String name, float value) {
|
||||
this(name, (Object) value);
|
||||
super(name, (Object) value);
|
||||
}
|
||||
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, double) */
|
||||
public SpanTermQueryBuilder(String name, double value) {
|
||||
this(name, (Object) value);
|
||||
super(name, (Object) value);
|
||||
}
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, Object) */
|
||||
public SpanTermQueryBuilder(String name, Object value) {
|
||||
super(name, value);
|
||||
}
|
||||
|
||||
private SpanTermQueryBuilder(String name, Object value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpanTermQueryBuilder boost(float boost) {
|
||||
this.boost = boost;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the query name for the filter that can be used when searching for matched_filters per hit.
|
||||
*/
|
||||
public SpanTermQueryBuilder queryName(String queryName) {
|
||||
this.queryName = queryName;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(SpanTermQueryParser.NAME);
|
||||
if (boost == -1 && queryName != null) {
|
||||
builder.field(name, value);
|
||||
} else {
|
||||
builder.startObject(name);
|
||||
builder.field("value", value);
|
||||
if (boost != -1) {
|
||||
builder.field("boost", boost);
|
||||
}
|
||||
if (queryName != null) {
|
||||
builder.field("_name", queryName);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
public SpanTermQueryBuilder() {
|
||||
// for testing and serialisation only
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String parserName() {
|
||||
return SpanTermQueryParser.NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query toQuery(QueryParseContext context) {
|
||||
BytesRef valueBytes = null;
|
||||
MapperService.SmartNameFieldMappers smartNameFieldMappers = context.smartFieldMappers(fieldName);
|
||||
if (smartNameFieldMappers != null) {
|
||||
if (smartNameFieldMappers.hasMapper()) {
|
||||
fieldName = smartNameFieldMappers.mapper().names().indexName();
|
||||
valueBytes = smartNameFieldMappers.mapper().indexedValueForSearch(value);
|
||||
}
|
||||
}
|
||||
if (valueBytes == null) {
|
||||
valueBytes = BytesRefs.toBytesRef(this.value);
|
||||
}
|
||||
|
||||
SpanTermQuery query = new SpanTermQuery(new Term(fieldName, valueBytes));
|
||||
query.setBoost(boost);
|
||||
if (queryName != null) {
|
||||
context.addNamedQuery(queryName, query);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
@ -19,21 +19,17 @@
|
||||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.spans.SpanTermQuery;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Parses the json representation of a spantermquery into the Elasticsearch internal
|
||||
* query builder representation.
|
||||
*/
|
||||
public class SpanTermQueryParser extends BaseQueryParserTemp {
|
||||
public class SpanTermQueryParser extends BaseQueryParser {
|
||||
|
||||
public static final String NAME = "span_term";
|
||||
|
||||
@ -47,18 +43,19 @@ public class SpanTermQueryParser extends BaseQueryParserTemp {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
||||
public QueryBuilder fromXContent(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
||||
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();
|
||||
|
||||
|
||||
String value = null;
|
||||
Object value = null;
|
||||
float boost = 1.0f;
|
||||
String queryName = null;
|
||||
token = parser.nextToken();
|
||||
@ -69,9 +66,9 @@ public class SpanTermQueryParser extends BaseQueryParserTemp {
|
||||
currentFieldName = parser.currentName();
|
||||
} else {
|
||||
if ("term".equals(currentFieldName)) {
|
||||
value = parser.text();
|
||||
value = parser.objectBytes();
|
||||
} else if ("value".equals(currentFieldName)) {
|
||||
value = parser.text();
|
||||
value = parser.objectBytes();
|
||||
} else if ("boost".equals(currentFieldName)) {
|
||||
boost = parser.floatValue();
|
||||
} else if ("_name".equals(currentFieldName)) {
|
||||
@ -83,7 +80,7 @@ public class SpanTermQueryParser extends BaseQueryParserTemp {
|
||||
}
|
||||
parser.nextToken();
|
||||
} else {
|
||||
value = parser.text();
|
||||
value = parser.objectBytes();
|
||||
// move to the next token
|
||||
parser.nextToken();
|
||||
}
|
||||
@ -92,23 +89,9 @@ public class SpanTermQueryParser extends BaseQueryParserTemp {
|
||||
throw new QueryParsingException(parseContext, "No value specified for term query");
|
||||
}
|
||||
|
||||
BytesRef valueBytes = null;
|
||||
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName);
|
||||
if (smartNameFieldMappers != null) {
|
||||
if (smartNameFieldMappers.hasMapper()) {
|
||||
fieldName = smartNameFieldMappers.mapper().names().indexName();
|
||||
valueBytes = smartNameFieldMappers.mapper().indexedValueForSearch(value);
|
||||
}
|
||||
}
|
||||
if (valueBytes == null) {
|
||||
valueBytes = new BytesRef(value);
|
||||
}
|
||||
|
||||
SpanTermQuery query = new SpanTermQuery(new Term(fieldName, valueBytes));
|
||||
query.setBoost(boost);
|
||||
if (queryName != null) {
|
||||
parseContext.addNamedQuery(queryName, query);
|
||||
}
|
||||
return query;
|
||||
SpanTermQueryBuilder result = new SpanTermQueryBuilder(fieldName, value);
|
||||
result.boost(boost).queryName(queryName);
|
||||
result.validate();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -22,178 +22,52 @@ package org.elasticsearch.index.query;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Streamable;
|
||||
import org.elasticsearch.common.lucene.BytesRefs;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A Query that matches documents containing a term.
|
||||
*/
|
||||
public class TermQueryBuilder extends QueryBuilder implements Streamable, BoostableQueryBuilder<TermQueryBuilder> {
|
||||
|
||||
private String fieldName;
|
||||
|
||||
private Object value;
|
||||
|
||||
private float boost = 1.0f;
|
||||
|
||||
private String queryName;
|
||||
|
||||
/**
|
||||
* Constructs a new term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
public class TermQueryBuilder extends BaseTermQueryBuilder<TermQueryBuilder> {
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, String) */
|
||||
public TermQueryBuilder(String fieldName, String value) {
|
||||
this(fieldName, (Object) value);
|
||||
super(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, int) */
|
||||
public TermQueryBuilder(String fieldName, int value) {
|
||||
this(fieldName, (Object) value);
|
||||
super(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, long) */
|
||||
public TermQueryBuilder(String fieldName, long value) {
|
||||
this(fieldName, (Object) value);
|
||||
super(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, float) */
|
||||
public TermQueryBuilder(String fieldName, float value) {
|
||||
this(fieldName, (Object) value);
|
||||
super(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, double) */
|
||||
public TermQueryBuilder(String fieldName, double value) {
|
||||
this(fieldName, (Object) value);
|
||||
super(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, boolean) */
|
||||
public TermQueryBuilder(String fieldName, boolean value) {
|
||||
this(fieldName, (Object) value);
|
||||
super(fieldName, (Object) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new term query.
|
||||
*
|
||||
* @param fieldName The name of the field
|
||||
* @param value The value of the term
|
||||
*/
|
||||
/** @see BaseTermQueryBuilder#BaseTermQueryBuilder(String, Object) */
|
||||
public TermQueryBuilder(String fieldName, Object value) {
|
||||
this.fieldName = fieldName;
|
||||
if (value instanceof String) {
|
||||
this.value = BytesRefs.toBytesRef(value);
|
||||
} else {
|
||||
this.value = value;
|
||||
}
|
||||
super(fieldName, value);
|
||||
}
|
||||
|
||||
public TermQueryBuilder() {
|
||||
// for serialization only
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the field name used in this query
|
||||
*/
|
||||
public String fieldName() {
|
||||
return this.fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value used in this query
|
||||
*/
|
||||
public Object value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the boost for this query. Documents matching this query will (in addition to the normal
|
||||
* weightings) have their score multiplied by the boost provided.
|
||||
*/
|
||||
@Override
|
||||
public TermQueryBuilder boost(float boost) {
|
||||
this.boost = boost;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the boost for this query.
|
||||
*/
|
||||
public float boost() {
|
||||
return this.boost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the query name for the query.
|
||||
*/
|
||||
public TermQueryBuilder queryName(String queryName) {
|
||||
this.queryName = queryName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the query name for the query.
|
||||
*/
|
||||
public String queryName() {
|
||||
return this.queryName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(TermQueryParser.NAME);
|
||||
Object valueToWrite = this.value;
|
||||
if (valueToWrite instanceof BytesRef) {
|
||||
valueToWrite = ((BytesRef) valueToWrite).utf8ToString();
|
||||
}
|
||||
if (boost == 1.0f && queryName == null) {
|
||||
builder.field(fieldName, valueToWrite);
|
||||
} else {
|
||||
builder.startObject(fieldName);
|
||||
builder.field("value", valueToWrite);
|
||||
if (boost != 1.0f) {
|
||||
builder.field("boost", boost);
|
||||
}
|
||||
if (queryName != null) {
|
||||
builder.field("_name", queryName);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query toQuery(QueryParseContext parseContext) {
|
||||
Query query = null;
|
||||
@ -211,55 +85,8 @@ public class TermQueryBuilder extends QueryBuilder implements Streamable, Boosta
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
QueryValidationException validationException = null;
|
||||
if (this.fieldName == null || this.fieldName.isEmpty()) {
|
||||
validationException = QueryValidationException.addValidationError("field name cannot be null or empty.", validationException);
|
||||
}
|
||||
if (this.value == null) {
|
||||
validationException = QueryValidationException.addValidationError("value cannot be null.", validationException);
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String parserName() {
|
||||
return TermQueryParser.NAME;
|
||||
}
|
||||
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
fieldName = in.readString();
|
||||
value = in.readGenericValue();
|
||||
boost = in.readFloat();
|
||||
queryName = in.readOptionalString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeString(fieldName);
|
||||
out.writeGenericValue(value);
|
||||
out.writeFloat(boost);
|
||||
out.writeOptionalString(queryName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(fieldName, value, boost, queryName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
TermQueryBuilder other = (TermQueryBuilder) obj;
|
||||
return Objects.equals(fieldName, other.fieldName) &&
|
||||
Objects.equals(value, other.value) &&
|
||||
Objects.equals(boost, other.boost) &&
|
||||
Objects.equals(queryName, other.queryName);
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ public class TermQueryParser extends BaseQueryParser {
|
||||
return new String[]{NAME};
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryBuilder fromXContent(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
||||
XContentParser parser = parseContext.parser();
|
||||
|
||||
|
@ -74,7 +74,7 @@ public abstract class BaseQueryTestCase<QB extends QueryBuilder & Streamable> ex
|
||||
* Setup for the whole base test class.
|
||||
*/
|
||||
@BeforeClass
|
||||
public static void init() throws IOException {
|
||||
public static void init() {
|
||||
Settings settings = ImmutableSettings.settingsBuilder()
|
||||
.put("name", BaseQueryTestCase.class.toString())
|
||||
.put("path.home", createTempDir())
|
||||
@ -150,7 +150,7 @@ public abstract class BaseQueryTestCase<QB extends QueryBuilder & Streamable> ex
|
||||
assertNotSame(newQuery, testQuery);
|
||||
assertEquals(newQuery, testQuery);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test creates the {@link Query} from the {@link QueryBuilder} under test and delegates the
|
||||
* assertions being made on the result to the implementing subclass.
|
||||
@ -171,15 +171,17 @@ public abstract class BaseQueryTestCase<QB extends QueryBuilder & Streamable> ex
|
||||
@Repeat(iterations = 20)
|
||||
public void testSerialization() throws IOException {
|
||||
testQuery = createTestQueryBuilder();
|
||||
BytesStreamOutput output = new BytesStreamOutput();
|
||||
testQuery.writeTo(output);
|
||||
|
||||
BytesStreamInput in = new BytesStreamInput(output.bytes());
|
||||
QB deserializedQuery = createEmptyQueryBuilder();
|
||||
deserializedQuery.readFrom(in);
|
||||
|
||||
assertEquals(deserializedQuery, testQuery);
|
||||
assertNotSame(deserializedQuery, testQuery);
|
||||
try (BytesStreamOutput output = new BytesStreamOutput()) {
|
||||
testQuery.writeTo(output);
|
||||
|
||||
try (BytesStreamInput in = new BytesStreamInput(output.bytes())) {
|
||||
QB deserializedQuery = createEmptyQueryBuilder();
|
||||
deserializedQuery.readFrom(in);
|
||||
|
||||
assertEquals(deserializedQuery, testQuery);
|
||||
assertNotSame(deserializedQuery, testQuery);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.io.stream.Streamable;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
@Ignore
|
||||
public abstract class BaseTermQueryTestCase<QB extends QueryBuilder & Streamable> extends BaseQueryTestCase<QB> {
|
||||
|
||||
protected Object createRandomValueObject() {
|
||||
Object value = null;
|
||||
switch (randomIntBetween(0, 3)) {
|
||||
case 0:
|
||||
value = randomBoolean();
|
||||
break;
|
||||
case 1:
|
||||
if (randomInt(10) > 0) {
|
||||
value = randomAsciiOfLength(8);
|
||||
} else {
|
||||
// generate unicode string in 10% of cases
|
||||
value = randomUnicodeOfLength(10);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
value = randomInt(10000);
|
||||
break;
|
||||
case 3:
|
||||
value = randomDouble();
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
protected abstract QB createQueryBuilder(String fieldName, Object value);
|
||||
|
||||
@Test
|
||||
public void testValidate() throws QueryParsingException {
|
||||
|
||||
QB queryBuilder = createQueryBuilder("all", "good");
|
||||
assertNull(queryBuilder.validate());
|
||||
|
||||
queryBuilder = createQueryBuilder(null, "Term");
|
||||
assertNotNull(queryBuilder.validate());
|
||||
assertThat(queryBuilder.validate().validationErrors().size(), is(1));
|
||||
|
||||
queryBuilder = createQueryBuilder("", "Term");
|
||||
assertNotNull(queryBuilder.validate());
|
||||
assertThat(queryBuilder.validate().validationErrors().size(), is(1));
|
||||
|
||||
queryBuilder = createQueryBuilder("", null);
|
||||
assertNotNull(queryBuilder.validate());
|
||||
assertThat(queryBuilder.validate().validationErrors().size(), is(2));
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.spans.SpanTermQuery;
|
||||
import org.elasticsearch.common.lucene.BytesRefs;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
public class SpanTermQueryBuilderTest extends BaseTermQueryTestCase<SpanTermQueryBuilder> {
|
||||
|
||||
@Override
|
||||
protected SpanTermQueryBuilder createEmptyQueryBuilder() {
|
||||
return new SpanTermQueryBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SpanTermQueryBuilder createQueryBuilder(String fieldName, Object value) {
|
||||
return new SpanTermQueryBuilder(fieldName, value);
|
||||
}
|
||||
|
||||
/** Returns a {@link SpanTermQueryBuilder} with random field name and value, optional random boost and queryname */
|
||||
@Override
|
||||
protected SpanTermQueryBuilder createTestQueryBuilder() {
|
||||
Object value = createRandomValueObject();
|
||||
SpanTermQueryBuilder query = new SpanTermQueryBuilder(randomAsciiOfLength(8), value);
|
||||
if (randomBoolean()) {
|
||||
query.boost(2.0f / randomIntBetween(1, 20));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
query.queryName(randomAsciiOfLength(8));
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
/** Checks the generated Lucene query against the {@link SpanTermQueryBuilder} it was created from. */
|
||||
@Override
|
||||
protected void assertLuceneQuery(SpanTermQueryBuilder queryBuilder, Query query, QueryParseContext context) throws IOException {
|
||||
assertThat(query, instanceOf(SpanTermQuery.class));
|
||||
assertThat(query.getBoost(), is(queryBuilder.boost()));
|
||||
SpanTermQuery termQuery = (SpanTermQuery) query;
|
||||
assertThat(termQuery.getTerm().field(), is(queryBuilder.fieldName()));
|
||||
assertThat(termQuery.getTerm().bytes(), is(BytesRefs.toBytesRef(queryBuilder.value())));
|
||||
if (queryBuilder.queryName() != null) {
|
||||
Query namedQuery = context.copyNamedFilters().get(queryBuilder.queryName());
|
||||
assertThat(namedQuery, equalTo((Query)termQuery));
|
||||
}
|
||||
}
|
||||
}
|
@ -22,13 +22,12 @@ package org.elasticsearch.index.query;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.elasticsearch.common.lucene.BytesRefs;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
public class TermQueryBuilderTest extends BaseQueryTestCase<TermQueryBuilder> {
|
||||
public class TermQueryBuilderTest extends BaseTermQueryTestCase<TermQueryBuilder> {
|
||||
|
||||
@Override
|
||||
protected TermQueryBuilder createEmptyQueryBuilder() {
|
||||
@ -39,27 +38,14 @@ public class TermQueryBuilderTest extends BaseQueryTestCase<TermQueryBuilder> {
|
||||
* @return a TermQuery with random field name and value, optional random boost and queryname
|
||||
*/
|
||||
@Override
|
||||
protected TermQueryBuilder createQueryBuilder(String fieldName, Object value) {
|
||||
return new TermQueryBuilder(fieldName, value);
|
||||
}
|
||||
|
||||
/** Returns a TermQuery with random field name and value, optional random boost and queryname. */
|
||||
@Override
|
||||
protected TermQueryBuilder createTestQueryBuilder() {
|
||||
Object value = null;
|
||||
switch (randomIntBetween(0, 3)) {
|
||||
case 0:
|
||||
value = randomBoolean();
|
||||
break;
|
||||
case 1:
|
||||
if (randomInt(10) > 0) {
|
||||
value = randomAsciiOfLength(8);
|
||||
} else {
|
||||
// generate unicode string in 10% of cases
|
||||
value = randomUnicodeOfLength(10);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
value = randomInt(10000);
|
||||
break;
|
||||
case 3:
|
||||
value = randomDouble();
|
||||
break;
|
||||
}
|
||||
Object value = createRandomValueObject();
|
||||
TermQueryBuilder query = new TermQueryBuilder(randomAsciiOfLength(8), value);
|
||||
if (randomBoolean()) {
|
||||
query.boost(2.0f / randomIntBetween(1, 20));
|
||||
@ -70,6 +56,7 @@ public class TermQueryBuilderTest extends BaseQueryTestCase<TermQueryBuilder> {
|
||||
return query;
|
||||
}
|
||||
|
||||
/** Validates the Lucene query that was generated from a given {@link TermQueryBuilder}*/
|
||||
@Override
|
||||
protected void assertLuceneQuery(TermQueryBuilder queryBuilder, Query query, QueryParseContext context) throws IOException {
|
||||
assertThat(query, instanceOf(TermQuery.class));
|
||||
@ -82,22 +69,4 @@ public class TermQueryBuilderTest extends BaseQueryTestCase<TermQueryBuilder> {
|
||||
assertThat(namedQuery, equalTo((Query)termQuery));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidate() throws QueryParsingException, IOException {
|
||||
TermQueryBuilder queryBuilder = new TermQueryBuilder("all", "good");
|
||||
assertNull(queryBuilder.validate());
|
||||
|
||||
queryBuilder = new TermQueryBuilder(null, "Term");
|
||||
assertNotNull(queryBuilder.validate());
|
||||
assertThat(queryBuilder.validate().validationErrors().size(), is(1));
|
||||
|
||||
queryBuilder = new TermQueryBuilder("", "Term");
|
||||
assertNotNull(queryBuilder.validate());
|
||||
assertThat(queryBuilder.validate().validationErrors().size(), is(1));
|
||||
|
||||
queryBuilder = new TermQueryBuilder("", null);
|
||||
assertNotNull(queryBuilder.validate());
|
||||
assertThat(queryBuilder.validate().validationErrors().size(), is(2));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user