Added control over Query used by MatchQuery with there are zero terms after analysis

This commit is contained in:
Chris Male 2012-11-22 22:13:29 +13:00
parent 9a90c1c3b5
commit 2541847945
4 changed files with 78 additions and 3 deletions

View File

@ -50,6 +50,11 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer
PHRASE_PREFIX
}
public static enum ZeroTermsQuery {
NONE,
ALL
}
private final String name;
private final Object text;
@ -80,6 +85,8 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer
private Boolean fuzzyTranspositions = null;
private ZeroTermsQuery zeroTermsQuery;
/**
* Constructs a new text query.
*/
@ -180,6 +187,11 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer
return this;
}
public MatchQueryBuilder zeroTermsQuery(ZeroTermsQuery zeroTermsQuery) {
this.zeroTermsQuery = zeroTermsQuery;
return this;
}
@Override
public void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(MatchQueryParser.NAME);
@ -226,6 +238,9 @@ public class MatchQueryBuilder extends BaseQueryBuilder implements BoostableQuer
if (lenient != null) {
builder.field("lenient", lenient);
}
if (zeroTermsQuery != null) {
builder.field("zero_terms_query", zeroTermsQuery.toString());
}
builder.endObject();
builder.endObject();

View File

@ -126,6 +126,15 @@ public class MatchQueryParser implements QueryParser {
matchQuery.setTranspositions(parser.booleanValue());
} else if ("lenient".equals(currentFieldName)) {
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 {
throw new QueryParsingException(parseContext.index(), "[match] query does not support [" + currentFieldName + "]");
}

View File

@ -24,18 +24,17 @@ import org.apache.lucene.analysis.CachingTokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.*;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.UnicodeUtil;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.ElasticSearchIllegalStateException;
import org.elasticsearch.ElasticSearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.io.FastStringReader;
import org.elasticsearch.common.lucene.search.MatchNoDocsQuery;
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.MapperService;
import org.elasticsearch.index.query.QueryParseContext;
@ -55,6 +54,11 @@ public class MatchQuery {
PHRASE_PREFIX
}
public static enum ZeroTermsQuery {
NONE,
ALL
}
protected final QueryParseContext parseContext;
protected String analyzer;
@ -77,6 +81,8 @@ public class MatchQuery {
protected boolean lenient;
protected ZeroTermsQuery zeroTermsQuery = ZeroTermsQuery.NONE;
public MatchQuery(QueryParseContext parseContext) {
this.parseContext = parseContext;
}
@ -125,6 +131,10 @@ public class MatchQuery {
this.lenient = lenient;
}
public void setZeroTermsQuery(ZeroTermsQuery zeroTermsQuery) {
this.zeroTermsQuery = zeroTermsQuery;
}
public Query parse(Type type, String fieldName, String text) {
FieldMapper mapper = null;
final String field;
@ -238,7 +248,7 @@ public class MatchQuery {
}
if (numTokens == 0) {
return MatchNoDocsQuery.INSTANCE;
return zeroTermsQuery();
} else if (type == Type.BOOLEAN) {
if (numTokens == 1) {
try {
@ -399,4 +409,8 @@ public class MatchQuery {
UnicodeUtil.UTF16toUTF8WithHash(attr.buffer(), 0, attr.length(), ref);
return ref;
}
protected Query zeroTermsQuery() {
return zeroTermsQuery == ZeroTermsQuery.NONE ? MatchNoDocsQuery.INSTANCE : Queries.MATCH_ALL_QUERY;
}
}

View File

@ -485,4 +485,41 @@ public class SimpleQueryTests extends AbstractNodesTests {
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));
}
}