Added control over Query used by MatchQuery with there are zero terms after analysis
This commit is contained in:
parent
9a90c1c3b5
commit
2541847945
|
@ -50,6 +50,11 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer
|
||||||
PHRASE_PREFIX
|
PHRASE_PREFIX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static enum ZeroTermsQuery {
|
||||||
|
NONE,
|
||||||
|
ALL
|
||||||
|
}
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private final Object text;
|
private final Object text;
|
||||||
|
@ -80,6 +85,8 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer
|
||||||
|
|
||||||
private Boolean fuzzyTranspositions = null;
|
private Boolean fuzzyTranspositions = null;
|
||||||
|
|
||||||
|
private ZeroTermsQuery zeroTermsQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new text query.
|
* Constructs a new text query.
|
||||||
*/
|
*/
|
||||||
|
@ -180,6 +187,11 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MatchQueryBuilder zeroTermsQuery(ZeroTermsQuery zeroTermsQuery) {
|
||||||
|
this.zeroTermsQuery = zeroTermsQuery;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject(MatchQueryParser.NAME);
|
builder.startObject(MatchQueryParser.NAME);
|
||||||
|
@ -226,6 +238,9 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer
|
||||||
if (lenient != null) {
|
if (lenient != null) {
|
||||||
builder.field("lenient", lenient);
|
builder.field("lenient", lenient);
|
||||||
}
|
}
|
||||||
|
if (zeroTermsQuery != null) {
|
||||||
|
builder.field("zero_terms_query", zeroTermsQuery.toString());
|
||||||
|
}
|
||||||
|
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
|
|
@ -126,6 +126,15 @@ public class MatchQueryParser implements QueryParser {
|
||||||
matchQuery.setTranspositions(parser.booleanValue());
|
matchQuery.setTranspositions(parser.booleanValue());
|
||||||
} else if ("lenient".equals(currentFieldName)) {
|
} else if ("lenient".equals(currentFieldName)) {
|
||||||
matchQuery.setLenient(parser.booleanValue());
|
matchQuery.setLenient(parser.booleanValue());
|
||||||
|
} else if ("zero_terms_query".equals(currentFieldName)) {
|
||||||
|
String zeroTermsDocs = parser.text();
|
||||||
|
if ("none".equalsIgnoreCase(zeroTermsDocs)) {
|
||||||
|
matchQuery.setZeroTermsQuery(MatchQuery.ZeroTermsQuery.NONE);
|
||||||
|
} else if ("all".equalsIgnoreCase(zeroTermsDocs)) {
|
||||||
|
matchQuery.setZeroTermsQuery(MatchQuery.ZeroTermsQuery.ALL);
|
||||||
|
} else {
|
||||||
|
throw new QueryParsingException(parseContext.index(), "Unsupported zero_terms_docs value [" + zeroTermsDocs +"]");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[match] query does not support [" + currentFieldName + "]");
|
throw new QueryParsingException(parseContext.index(), "[match] query does not support [" + currentFieldName + "]");
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,18 +24,17 @@ import org.apache.lucene.analysis.CachingTokenFilter;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
|
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
|
||||||
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
|
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
|
||||||
import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
|
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.search.*;
|
import org.apache.lucene.search.*;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.UnicodeUtil;
|
import org.apache.lucene.util.UnicodeUtil;
|
||||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||||
import org.elasticsearch.ElasticSearchIllegalStateException;
|
import org.elasticsearch.ElasticSearchIllegalStateException;
|
||||||
import org.elasticsearch.ElasticSearchParseException;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.io.FastStringReader;
|
import org.elasticsearch.common.io.FastStringReader;
|
||||||
import org.elasticsearch.common.lucene.search.MatchNoDocsQuery;
|
import org.elasticsearch.common.lucene.search.MatchNoDocsQuery;
|
||||||
import org.elasticsearch.common.lucene.search.MultiPhrasePrefixQuery;
|
import org.elasticsearch.common.lucene.search.MultiPhrasePrefixQuery;
|
||||||
|
import org.elasticsearch.common.lucene.search.Queries;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
|
@ -55,6 +54,11 @@ public class MatchQuery {
|
||||||
PHRASE_PREFIX
|
PHRASE_PREFIX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static enum ZeroTermsQuery {
|
||||||
|
NONE,
|
||||||
|
ALL
|
||||||
|
}
|
||||||
|
|
||||||
protected final QueryParseContext parseContext;
|
protected final QueryParseContext parseContext;
|
||||||
|
|
||||||
protected String analyzer;
|
protected String analyzer;
|
||||||
|
@ -77,6 +81,8 @@ public class MatchQuery {
|
||||||
|
|
||||||
protected boolean lenient;
|
protected boolean lenient;
|
||||||
|
|
||||||
|
protected ZeroTermsQuery zeroTermsQuery = ZeroTermsQuery.NONE;
|
||||||
|
|
||||||
public MatchQuery(QueryParseContext parseContext) {
|
public MatchQuery(QueryParseContext parseContext) {
|
||||||
this.parseContext = parseContext;
|
this.parseContext = parseContext;
|
||||||
}
|
}
|
||||||
|
@ -125,6 +131,10 @@ public class MatchQuery {
|
||||||
this.lenient = lenient;
|
this.lenient = lenient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setZeroTermsQuery(ZeroTermsQuery zeroTermsQuery) {
|
||||||
|
this.zeroTermsQuery = zeroTermsQuery;
|
||||||
|
}
|
||||||
|
|
||||||
public Query parse(Type type, String fieldName, String text) {
|
public Query parse(Type type, String fieldName, String text) {
|
||||||
FieldMapper mapper = null;
|
FieldMapper mapper = null;
|
||||||
final String field;
|
final String field;
|
||||||
|
@ -238,7 +248,7 @@ public class MatchQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numTokens == 0) {
|
if (numTokens == 0) {
|
||||||
return MatchNoDocsQuery.INSTANCE;
|
return zeroTermsQuery();
|
||||||
} else if (type == Type.BOOLEAN) {
|
} else if (type == Type.BOOLEAN) {
|
||||||
if (numTokens == 1) {
|
if (numTokens == 1) {
|
||||||
try {
|
try {
|
||||||
|
@ -399,4 +409,8 @@ public class MatchQuery {
|
||||||
UnicodeUtil.UTF16toUTF8WithHash(attr.buffer(), 0, attr.length(), ref);
|
UnicodeUtil.UTF16toUTF8WithHash(attr.buffer(), 0, attr.length(), ref);
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Query zeroTermsQuery() {
|
||||||
|
return zeroTermsQuery == ZeroTermsQuery.NONE ? MatchNoDocsQuery.INSTANCE : Queries.MATCH_ALL_QUERY;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -485,4 +485,41 @@ public class SimpleQueryTests extends AbstractNodesTests {
|
||||||
assertThat("1", equalTo(searchResponse.hits().getAt(0).id()));
|
assertThat("1", equalTo(searchResponse.hits().getAt(0).id()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatchQueryZeroTermsQuery() {
|
||||||
|
try {
|
||||||
|
client.admin().indices().prepareDelete("test").execute().actionGet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
client.admin().indices().prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder().put("number_of_shards", 1)).execute().actionGet();
|
||||||
|
client.prepareIndex("test", "type1", "1").setSource("field1", "value1").execute().actionGet();
|
||||||
|
client.prepareIndex("test", "type1", "2").setSource("field1", "value2").execute().actionGet();
|
||||||
|
client.admin().indices().prepareRefresh("test").execute().actionGet();
|
||||||
|
|
||||||
|
BoolQueryBuilder boolQuery = boolQuery()
|
||||||
|
.must(matchQuery("field1", "a").zeroTermsQuery(MatchQueryBuilder.ZeroTermsQuery.NONE))
|
||||||
|
.must(matchQuery("field1", "value1").zeroTermsQuery(MatchQueryBuilder.ZeroTermsQuery.NONE));
|
||||||
|
SearchResponse searchResponse = client.prepareSearch()
|
||||||
|
.setQuery(boolQuery)
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(searchResponse.hits().totalHits(), equalTo(0l));
|
||||||
|
|
||||||
|
boolQuery = boolQuery()
|
||||||
|
.must(matchQuery("field1", "a").zeroTermsQuery(MatchQueryBuilder.ZeroTermsQuery.ALL))
|
||||||
|
.must(matchQuery("field1", "value1").zeroTermsQuery(MatchQueryBuilder.ZeroTermsQuery.ALL));
|
||||||
|
searchResponse = client.prepareSearch()
|
||||||
|
.setQuery(boolQuery)
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
|
||||||
|
|
||||||
|
boolQuery = boolQuery()
|
||||||
|
.must(matchQuery("field1", "a").zeroTermsQuery(MatchQueryBuilder.ZeroTermsQuery.ALL));
|
||||||
|
searchResponse = client.prepareSearch()
|
||||||
|
.setQuery(boolQuery)
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue