change numeric term or query parser field query to use range filter/query and not encoded Term query
This commit is contained in:
parent
cb8faaa13f
commit
4f91152b3d
|
@ -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>.
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -319,18 +319,18 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
|
|||
return value.toString();
|
||||
}
|
||||
|
||||
@Override public boolean useTermQueryWithQueryString() {
|
||||
@Override public Query queryStringTermQuery(Term term) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public boolean useFieldQueryWithQueryString() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public Query termQuery(String value) {
|
||||
@Override public Query fieldQuery(String value) {
|
||||
return new TermQuery(new Term(names.indexName(), indexedValue(value)));
|
||||
}
|
||||
|
||||
@Override public Query queryStringTermQuery(Term term) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public Filter fieldFilter(String value) {
|
||||
return new TermFilter(new Term(names.indexName(), indexedValue(value)));
|
||||
}
|
||||
|
|
|
@ -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).
|
||||
*/
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
boost: 1.2,
|
||||
queries : [
|
||||
{
|
||||
term : { age : 34 }
|
||||
term : { "name.first" : "first" }
|
||||
},
|
||||
{
|
||||
term : { age : 35 }
|
||||
term : { "name.last" : "last" }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
field : { age : 34 }
|
||||
"field" : { "age" : 34 }
|
||||
}
|
Loading…
Reference in New Issue