change numeric term or query parser field query to use range filter/query and not encoded Term query

This commit is contained in:
kimchy 2010-04-27 12:33:24 +03:00
parent cb8faaa13f
commit 4f91152b3d
9 changed files with 93 additions and 56 deletions

View File

@ -162,15 +162,15 @@ public interface FieldMapper<T> {
String indexedValue(T value);
/**
* Should the field query {@link #termQuery(String)} be used when detecting this
* Should the field query {@link #fieldQuery(String)} be used when detecting this
* field in query string.
*/
boolean useTermQueryWithQueryString();
boolean useFieldQueryWithQueryString();
/**
* A field query for the specified value.
*/
Query termQuery(String value);
Query fieldQuery(String value);
/**
* A term query to use when parsing a query string. Can return <tt>null</tt>.

View File

@ -110,7 +110,7 @@ public class JsonAllFieldMapper extends JsonFieldMapper<Void> implements AllFiel
return new AllTermQuery(term);
}
@Override public Query termQuery(String value) {
@Override public Query fieldQuery(String value) {
return new AllTermQuery(new Term(names.indexName(), value));
}

View File

@ -319,18 +319,18 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
return value.toString();
}
@Override public boolean useTermQueryWithQueryString() {
return false;
}
@Override public Query termQuery(String value) {
return new TermQuery(new Term(names.indexName(), indexedValue(value)));
}
@Override public Query queryStringTermQuery(Term term) {
return null;
}
@Override public boolean useFieldQueryWithQueryString() {
return false;
}
@Override public Query fieldQuery(String value) {
return new TermQuery(new Term(names.indexName(), indexedValue(value)));
}
@Override public Filter fieldFilter(String value) {
return new TermFilter(new Term(names.indexName(), indexedValue(value)));
}

View File

@ -23,6 +23,8 @@ import org.apache.lucene.analysis.NumericTokenStream;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.NumericUtils;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.util.ThreadLocals;
@ -115,10 +117,30 @@ public abstract class JsonNumberFieldMapper<T extends Number> extends JsonFieldM
/**
* Use the field query created here when matching on numbers.
*/
@Override public boolean useTermQueryWithQueryString() {
@Override public boolean useFieldQueryWithQueryString() {
return true;
}
/**
* Numeric field level query are basically range queries with same value and included. That's the recommended
* way to execute it.
*/
@Override public Query fieldQuery(String value) {
return rangeQuery(value, value, true, true);
}
/**
* Numeric field level filter are basically range queries with same value and included. That's the recommended
* way to execute it.
*/
@Override public Filter fieldFilter(String value) {
return rangeFilter(value, value, true, true);
}
@Override public abstract Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper);
@Override public abstract Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper);
/**
* Override the default behavior (to return the string, and return the actual Number instance).
*/

View File

@ -93,7 +93,7 @@ public class TermJsonQueryParser extends AbstractIndexComponent implements JsonQ
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName);
if (smartNameFieldMappers != null) {
if (smartNameFieldMappers.hasMapper()) {
query = smartNameFieldMappers.mapper().termQuery(value);
query = smartNameFieldMappers.mapper().fieldQuery(value);
}
}
if (query == null) {

View File

@ -81,10 +81,11 @@ public class MapperQueryParser extends QueryParser {
if (fieldMappers != null) {
currentMapper = fieldMappers.fieldMappers().mapper();
if (currentMapper != null) {
Query query;
if (currentMapper.useTermQueryWithQueryString()) {
query = currentMapper.termQuery(queryText);
} else {
Query query = null;
if (currentMapper.useFieldQueryWithQueryString()) {
query = currentMapper.fieldQuery(queryText);
}
if (query == null) {
query = super.getFieldQuery(currentMapper.names().indexName(), queryText);
}
return wrapSmartNameQuery(query, fieldMappers, indexCache);

View File

@ -158,7 +158,7 @@ public class SimpleJsonIndexQueryParserTests {
@Test public void testDisMaxBuilder() throws Exception {
IndexQueryParser queryParser = newQueryParser();
Query parsedQuery = queryParser.parse(disMaxQuery().boost(1.2f).tieBreaker(0.7f).add(termQuery("age", 34)).add(termQuery("age", 35)));
Query parsedQuery = queryParser.parse(disMaxQuery().boost(1.2f).tieBreaker(0.7f).add(termQuery("name.first", "first")).add(termQuery("name.last", "last")));
assertThat(parsedQuery, instanceOf(DisjunctionMaxQuery.class));
DisjunctionMaxQuery disjunctionMaxQuery = (DisjunctionMaxQuery) parsedQuery;
assertThat((double) disjunctionMaxQuery.getBoost(), closeTo(1.2, 0.01));
@ -168,11 +168,11 @@ public class SimpleJsonIndexQueryParserTests {
Query firstQ = disjuncts.get(0);
assertThat(firstQ, instanceOf(TermQuery.class));
assertThat(((TermQuery) firstQ).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
assertThat(((TermQuery) firstQ).getTerm(), equalTo(new Term("name.first", "first")));
Query secondsQ = disjuncts.get(1);
assertThat(secondsQ, instanceOf(TermQuery.class));
assertThat(((TermQuery) secondsQ).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(35))));
assertThat(((TermQuery) secondsQ).getTerm(), equalTo(new Term("name.last", "last")));
}
@Test public void testDisMax() throws Exception {
@ -188,49 +188,57 @@ public class SimpleJsonIndexQueryParserTests {
Query firstQ = disjuncts.get(0);
assertThat(firstQ, instanceOf(TermQuery.class));
assertThat(((TermQuery) firstQ).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
assertThat(((TermQuery) firstQ).getTerm(), equalTo(new Term("name.first", "first")));
Query secondsQ = disjuncts.get(1);
assertThat(secondsQ, instanceOf(TermQuery.class));
assertThat(((TermQuery) secondsQ).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(35))));
assertThat(((TermQuery) secondsQ).getTerm(), equalTo(new Term("name.last", "last")));
}
@Test public void testTermQueryBuilder() throws IOException {
IndexQueryParser queryParser = newQueryParser();
Query parsedQuery = queryParser.parse(termQuery("age", 34).buildAsBytes());
assertThat(parsedQuery, instanceOf(TermQuery.class));
TermQuery termQuery = (TermQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
assertThat(parsedQuery, instanceOf(NumericRangeQuery.class));
NumericRangeQuery fieldQuery = (NumericRangeQuery) parsedQuery;
assertThat(fieldQuery.getMin().intValue(), equalTo(34));
assertThat(fieldQuery.getMax().intValue(), equalTo(34));
assertThat(fieldQuery.includesMax(), equalTo(true));
assertThat(fieldQuery.includesMin(), equalTo(true));
}
@Test public void testTermQuery() throws IOException {
IndexQueryParser queryParser = newQueryParser();
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/json/term.json");
Query parsedQuery = queryParser.parse(query);
assertThat(parsedQuery, instanceOf(TermQuery.class));
TermQuery termQuery = (TermQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
assertThat(parsedQuery, instanceOf(NumericRangeQuery.class));
NumericRangeQuery fieldQuery = (NumericRangeQuery) parsedQuery;
assertThat(fieldQuery.getMin().intValue(), equalTo(34));
assertThat(fieldQuery.getMax().intValue(), equalTo(34));
assertThat(fieldQuery.includesMax(), equalTo(true));
assertThat(fieldQuery.includesMin(), equalTo(true));
}
@Test public void testFieldQueryBuilder1() throws IOException {
IndexQueryParser queryParser = newQueryParser();
Query parsedQuery = queryParser.parse(fieldQuery("age", 34).buildAsBytes());
assertThat(parsedQuery, instanceOf(TermQuery.class));
TermQuery termQuery = (TermQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
assertThat(parsedQuery, instanceOf(NumericRangeQuery.class));
NumericRangeQuery fieldQuery = (NumericRangeQuery) parsedQuery;
assertThat(fieldQuery.getMin().intValue(), equalTo(34));
assertThat(fieldQuery.getMax().intValue(), equalTo(34));
assertThat(fieldQuery.includesMax(), equalTo(true));
assertThat(fieldQuery.includesMin(), equalTo(true));
}
@Test public void testFieldQuery1() throws IOException {
IndexQueryParser queryParser = newQueryParser();
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/json/field1.json");
Query parsedQuery = queryParser.parse(query);
assertThat(parsedQuery, instanceOf(TermQuery.class));
TermQuery termQuery = (TermQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
assertThat(parsedQuery, instanceOf(NumericRangeQuery.class));
NumericRangeQuery fieldQuery = (NumericRangeQuery) parsedQuery;
assertThat(fieldQuery.getMin().intValue(), equalTo(34));
assertThat(fieldQuery.getMax().intValue(), equalTo(34));
assertThat(fieldQuery.includesMax(), equalTo(true));
assertThat(fieldQuery.includesMin(), equalTo(true));
}
@Test public void testFieldQuery2() throws IOException {
@ -251,31 +259,37 @@ public class SimpleJsonIndexQueryParserTests {
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/json/field3.json");
Query parsedQuery = queryParser.parse(query);
assertThat((double) parsedQuery.getBoost(), closeTo(2.0, 0.01));
assertThat(parsedQuery, instanceOf(TermQuery.class));
TermQuery termQuery = (TermQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
assertThat(parsedQuery, instanceOf(NumericRangeQuery.class));
NumericRangeQuery fieldQuery = (NumericRangeQuery) parsedQuery;
assertThat(fieldQuery.getMin().intValue(), equalTo(34));
assertThat(fieldQuery.getMax().intValue(), equalTo(34));
assertThat(fieldQuery.includesMax(), equalTo(true));
assertThat(fieldQuery.includesMin(), equalTo(true));
}
@Test public void testTermWithBoostQueryBuilder() throws IOException {
IndexQueryParser queryParser = newQueryParser();
Query parsedQuery = queryParser.parse(termQuery("age", 34).boost(2.0f));
assertThat(parsedQuery, instanceOf(TermQuery.class));
TermQuery termQuery = (TermQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
assertThat((double) termQuery.getBoost(), closeTo(2.0, 0.01));
assertThat(parsedQuery, instanceOf(NumericRangeQuery.class));
NumericRangeQuery fieldQuery = (NumericRangeQuery) parsedQuery;
assertThat(fieldQuery.getMin().intValue(), equalTo(34));
assertThat(fieldQuery.getMax().intValue(), equalTo(34));
assertThat(fieldQuery.includesMax(), equalTo(true));
assertThat(fieldQuery.includesMin(), equalTo(true));
assertThat((double) fieldQuery.getBoost(), closeTo(2.0, 0.01));
}
@Test public void testTermWithBoostQuery() throws IOException {
IndexQueryParser queryParser = newQueryParser();
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/json/term-with-boost.json");
Query parsedQuery = queryParser.parse(query);
assertThat(parsedQuery, instanceOf(TermQuery.class));
TermQuery termQuery = (TermQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
assertThat((double) termQuery.getBoost(), closeTo(2.0, 0.01));
assertThat(parsedQuery, instanceOf(NumericRangeQuery.class));
NumericRangeQuery fieldQuery = (NumericRangeQuery) parsedQuery;
assertThat(fieldQuery.getMin().intValue(), equalTo(34));
assertThat(fieldQuery.getMax().intValue(), equalTo(34));
assertThat(fieldQuery.includesMax(), equalTo(true));
assertThat(fieldQuery.includesMin(), equalTo(true));
assertThat((double) fieldQuery.getBoost(), closeTo(2.0, 0.01));
}
@Test public void testPrefixQueryBuilder() throws IOException {

View File

@ -4,10 +4,10 @@
boost: 1.2,
queries : [
{
term : { age : 34 }
term : { "name.first" : "first" }
},
{
term : { age : 35 }
term : { "name.last" : "last" }
}
]
}

View File

@ -1,3 +1,3 @@
{
field : { age : 34 }
"field" : { "age" : 34 }
}