Refactors PrefixQuery
Relates to #10217 Closes #12032 This PR is against the query-refactoring branch.
This commit is contained in:
parent
a4e9f642c2
commit
37c6347bce
|
@ -147,7 +147,7 @@ public abstract class BaseTermQueryBuilder<QB extends BaseTermQueryBuilder<QB>>
|
|||
|
||||
@Override
|
||||
protected final int doHashCode() {
|
||||
return Objects.hash(getClass(), fieldName, value);
|
||||
return Objects.hash(fieldName, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,9 +19,20 @@
|
|||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
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.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.index.mapper.MappedFieldType;
|
||||
import org.elasticsearch.index.query.support.QueryParsers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A Query that matches documents containing terms with a specified prefix.
|
||||
|
@ -30,10 +41,10 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder<PrefixQueryBuilder>
|
|||
|
||||
public static final String NAME = "prefix";
|
||||
|
||||
private final String name;
|
||||
|
||||
private final String prefix;
|
||||
|
||||
private final String fieldName;
|
||||
|
||||
private final String value;
|
||||
|
||||
private String rewrite;
|
||||
|
||||
static final PrefixQueryBuilder PROTOTYPE = new PrefixQueryBuilder(null, null);
|
||||
|
@ -41,12 +52,20 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder<PrefixQueryBuilder>
|
|||
/**
|
||||
* A Query that matches documents containing terms with a specified prefix.
|
||||
*
|
||||
* @param name The name of the field
|
||||
* @param prefix The prefix query
|
||||
* @param fieldName The name of the field
|
||||
* @param value The prefix query
|
||||
*/
|
||||
public PrefixQueryBuilder(String name, String prefix) {
|
||||
this.name = name;
|
||||
this.prefix = prefix;
|
||||
public PrefixQueryBuilder(String fieldName, String value) {
|
||||
this.fieldName = fieldName;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String fieldName() {
|
||||
return this.fieldName;
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public PrefixQueryBuilder rewrite(String rewrite) {
|
||||
|
@ -54,11 +73,15 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder<PrefixQueryBuilder>
|
|||
return this;
|
||||
}
|
||||
|
||||
public String rewrite() {
|
||||
return this.rewrite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(NAME);
|
||||
builder.startObject(name);
|
||||
builder.field("prefix", prefix);
|
||||
builder.startObject(fieldName);
|
||||
builder.field("prefix", this.value);
|
||||
if (rewrite != null) {
|
||||
builder.field("rewrite", rewrite);
|
||||
}
|
||||
|
@ -71,4 +94,62 @@ public class PrefixQueryBuilder extends AbstractQueryBuilder<PrefixQueryBuilder>
|
|||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Query doToQuery(QueryParseContext parseContext) throws IOException {
|
||||
MultiTermQuery.RewriteMethod method = QueryParsers.parseRewriteMethod(parseContext.parseFieldMatcher(), rewrite, null);
|
||||
|
||||
Query query = null;
|
||||
MappedFieldType fieldType = parseContext.fieldMapper(fieldName);
|
||||
if (fieldType != null) {
|
||||
query = fieldType.prefixQuery(value, method, parseContext);
|
||||
}
|
||||
if (query == null) {
|
||||
PrefixQuery prefixQuery = new PrefixQuery(new Term(fieldName, BytesRefs.toBytesRef(value)));
|
||||
if (method != null) {
|
||||
prefixQuery.setRewriteMethod(method);
|
||||
}
|
||||
query = prefixQuery;
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryValidationException validate() {
|
||||
QueryValidationException validationException = null;
|
||||
if (Strings.isEmpty(this.fieldName)) {
|
||||
validationException = addValidationError("field name cannot be null or empty.", validationException);
|
||||
}
|
||||
if (this.value == null) {
|
||||
validationException = addValidationError("query text cannot be null", validationException);
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PrefixQueryBuilder doReadFrom(StreamInput in) throws IOException {
|
||||
PrefixQueryBuilder prefixQueryBuilder = new PrefixQueryBuilder(in.readString(), in.readString());
|
||||
prefixQueryBuilder.rewrite = in.readOptionalString();
|
||||
return prefixQueryBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doWriteTo(StreamOutput out) throws IOException {
|
||||
out.writeString(fieldName);
|
||||
out.writeString(value);
|
||||
out.writeOptionalString(rewrite);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final int doHashCode() {
|
||||
return Objects.hash(fieldName, value, rewrite);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doEquals(PrefixQueryBuilder other) {
|
||||
return Objects.equals(fieldName, other.fieldName) &&
|
||||
Objects.equals(value, other.value) &&
|
||||
Objects.equals(rewrite, other.rewrite);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,22 +19,15 @@
|
|||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
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.inject.Inject;
|
||||
import org.elasticsearch.common.lucene.BytesRefs;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
import org.elasticsearch.index.query.support.QueryParsers;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PrefixQueryParser extends BaseQueryParserTemp {
|
||||
public class PrefixQueryParser extends BaseQueryParser {
|
||||
|
||||
@Inject
|
||||
public PrefixQueryParser() {
|
||||
|
@ -46,14 +39,14 @@ public class PrefixQueryParser extends BaseQueryParserTemp {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
||||
public QueryBuilder fromXContent(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
||||
XContentParser parser = parseContext.parser();
|
||||
|
||||
String fieldName = parser.currentName();
|
||||
String rewriteMethod = null;
|
||||
String queryName = null;
|
||||
|
||||
String value = null;
|
||||
String rewrite = null;
|
||||
|
||||
String queryName = null;
|
||||
float boost = AbstractQueryBuilder.DEFAULT_BOOST;
|
||||
String currentFieldName = null;
|
||||
XContentParser.Token token;
|
||||
|
@ -75,7 +68,7 @@ public class PrefixQueryParser extends BaseQueryParserTemp {
|
|||
} else if ("boost".equals(currentFieldName)) {
|
||||
boost = parser.floatValue();
|
||||
} else if ("rewrite".equals(currentFieldName)) {
|
||||
rewriteMethod = parser.textOrNull();
|
||||
rewrite = parser.textOrNull();
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext, "[regexp] query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
|
@ -94,26 +87,10 @@ public class PrefixQueryParser extends BaseQueryParserTemp {
|
|||
if (value == null) {
|
||||
throw new QueryParsingException(parseContext, "No value specified for prefix query");
|
||||
}
|
||||
|
||||
MultiTermQuery.RewriteMethod method = QueryParsers.parseRewriteMethod(parseContext.parseFieldMatcher(), rewriteMethod, null);
|
||||
|
||||
Query query = null;
|
||||
MappedFieldType fieldType = parseContext.fieldMapper(fieldName);
|
||||
if (fieldType != null) {
|
||||
query = fieldType.prefixQuery(value, method, parseContext);
|
||||
}
|
||||
if (query == null) {
|
||||
PrefixQuery prefixQuery = new PrefixQuery(new Term(fieldName, BytesRefs.toBytesRef(value)));
|
||||
if (method != null) {
|
||||
prefixQuery.setRewriteMethod(method);
|
||||
}
|
||||
query = prefixQuery;
|
||||
}
|
||||
query.setBoost(boost);
|
||||
if (queryName != null) {
|
||||
parseContext.addNamedQuery(queryName, query);
|
||||
}
|
||||
return query;
|
||||
return new PrefixQueryBuilder(fieldName, value)
|
||||
.rewrite(rewrite)
|
||||
.boost(boost)
|
||||
.queryName(queryName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.index.Term;
|
||||
import org.apache.lucene.search.MultiTermQuery;
|
||||
import org.apache.lucene.search.PrefixQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.lucene.BytesRefs;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
import org.elasticsearch.index.query.support.QueryParsers;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
public class PrefixQueryBuilderTest extends BaseQueryTestCase<PrefixQueryBuilder> {
|
||||
|
||||
@Override
|
||||
protected PrefixQueryBuilder doCreateTestQueryBuilder() {
|
||||
String fieldName = randomBoolean() ? STRING_FIELD_NAME : randomAsciiOfLengthBetween(1, 10);
|
||||
String value = randomAsciiOfLengthBetween(1, 10);
|
||||
PrefixQueryBuilder query = new PrefixQueryBuilder(fieldName, value);
|
||||
|
||||
if (randomBoolean()) {
|
||||
query.rewrite(getRandomRewriteMethod());
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Query doCreateExpectedQuery(PrefixQueryBuilder queryBuilder, QueryParseContext context) throws IOException {
|
||||
//norelease fix to be removed to avoid NPE on unmapped fields (Dtests.seed=BF5D7566DECBC5B1)
|
||||
context.parseFieldMatcher(randomBoolean() ? ParseFieldMatcher.EMPTY : ParseFieldMatcher.STRICT);
|
||||
|
||||
MultiTermQuery.RewriteMethod method = QueryParsers.parseRewriteMethod(context.parseFieldMatcher(), queryBuilder.rewrite(), null);
|
||||
|
||||
Query query = null;
|
||||
MappedFieldType fieldType = context.fieldMapper(queryBuilder.fieldName());
|
||||
if (fieldType != null) {
|
||||
query = fieldType.prefixQuery(queryBuilder.value(), method, context);
|
||||
}
|
||||
if (query == null) {
|
||||
PrefixQuery prefixQuery = new PrefixQuery(new Term(queryBuilder.fieldName(), BytesRefs.toBytesRef(queryBuilder.value())));
|
||||
if (method != null) {
|
||||
prefixQuery.setRewriteMethod(method);
|
||||
}
|
||||
query = prefixQuery;
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidate() {
|
||||
PrefixQueryBuilder prefixQueryBuilder = new PrefixQueryBuilder("", "prefix");
|
||||
assertThat(prefixQueryBuilder.validate().validationErrors().size(), is(1));
|
||||
|
||||
prefixQueryBuilder = new PrefixQueryBuilder("field", null);
|
||||
assertThat(prefixQueryBuilder.validate().validationErrors().size(), is(1));
|
||||
|
||||
prefixQueryBuilder = new PrefixQueryBuilder("field", "prefix");
|
||||
assertNull(prefixQueryBuilder.validate());
|
||||
|
||||
prefixQueryBuilder = new PrefixQueryBuilder(null, null);
|
||||
assertThat(prefixQueryBuilder.validate().validationErrors().size(), is(2));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue