Skip to content

Commit

Permalink
Added control over Query used by MatchQuery with there are zero terms…
Browse files Browse the repository at this point in the history
… after analysis
  • Loading branch information
chrismale committed Nov 22, 2012
1 parent 9a90c1c commit 2541847
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 3 deletions.
15 changes: 15 additions & 0 deletions src/main/java/org/elasticsearch/index/query/MatchQueryBuilder.java
Expand Up @@ -50,6 +50,11 @@ public static enum Type {
PHRASE_PREFIX
}

public static enum ZeroTermsQuery {
NONE,
ALL
}

private final String name;

private final Object text;
Expand Down Expand Up @@ -80,6 +85,8 @@ public static enum Type {

private Boolean fuzzyTranspositions = null;

private ZeroTermsQuery zeroTermsQuery;

/**
* Constructs a new text query.
*/
Expand Down Expand Up @@ -180,6 +187,11 @@ public MatchQueryBuilder setLenient(boolean lenient) {
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);
Expand Down Expand Up @@ -226,6 +238,9 @@ public void doXContent(XContentBuilder builder, Params params) throws IOExceptio
if (lenient != null) {
builder.field("lenient", lenient);
}
if (zeroTermsQuery != null) {
builder.field("zero_terms_query", zeroTermsQuery.toString());
}

builder.endObject();
builder.endObject();
Expand Down
Expand Up @@ -126,6 +126,15 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
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 + "]");
}
Expand Down
20 changes: 17 additions & 3 deletions src/main/java/org/elasticsearch/index/search/MatchQuery.java
Expand Up @@ -24,18 +24,17 @@
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;
Expand All @@ -55,6 +54,11 @@ public static enum Type {
PHRASE_PREFIX
}

public static enum ZeroTermsQuery {
NONE,
ALL
}

protected final QueryParseContext parseContext;

protected String analyzer;
Expand All @@ -77,6 +81,8 @@ public static enum Type {

protected boolean lenient;

protected ZeroTermsQuery zeroTermsQuery = ZeroTermsQuery.NONE;

public MatchQuery(QueryParseContext parseContext) {
this.parseContext = parseContext;
}
Expand Down Expand Up @@ -125,6 +131,10 @@ public void setLenient(boolean lenient) {
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;
Expand Down Expand Up @@ -238,7 +248,7 @@ public Query parse(Type type, String fieldName, String text) {
}

if (numTokens == 0) {
return MatchNoDocsQuery.INSTANCE;
return zeroTermsQuery();
} else if (type == Type.BOOLEAN) {
if (numTokens == 1) {
try {
Expand Down Expand Up @@ -399,4 +409,8 @@ private static BytesRef termToByteRef(CharTermAttribute attr, BytesRef ref) {
UnicodeUtil.UTF16toUTF8WithHash(attr.buffer(), 0, attr.length(), ref);
return ref;
}

protected Query zeroTermsQuery() {
return zeroTermsQuery == ZeroTermsQuery.NONE ? MatchNoDocsQuery.INSTANCE : Queries.MATCH_ALL_QUERY;
}
}
Expand Up @@ -485,4 +485,41 @@ public void testMultiMatchQuery() throws Exception {
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));
}

}

0 comments on commit 2541847

Please sign in to comment.