Browse Source

Query enhancement: Enable Lucene ranking behaviour for queries on numeric fields.
This changes the default ranking behaviour of single-term queries on numeric fields to use the usual Lucene TermQuery scoring logic rather than a constant-scoring wrapper.

Closes #10628

markharwood 10 years ago
parent
commit
1b8b993912

+ 5 - 0
docs/reference/migration/migrate_2_0.asciidoc

@@ -381,6 +381,11 @@ be used separately to control whether `routing_nodes` should be returned.
 
 === Query DSL
 
+Change to ranking behaviour: single-term queries on numeric fields now score in the same way as string fields (use of IDF, norms if enabled). 
+Previously, term queries on numeric fields were deliberately prevented from using the usual Lucene scoring logic and this behaviour was undocumented and, to some, unexpected.
+If the introduction of scoring to numeric fields is undesirable for your query clauses the fix is simple: wrap them in a `constant_score` or use a `filter` expression instead.  
+
+
 The `fuzzy_like_this` and `fuzzy_like_this_field` queries have been removed.
 
 The `limit` filter is deprecated and becomes a no-op. You can achieve similar

+ 1 - 3
src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java

@@ -34,7 +34,6 @@ import org.apache.lucene.index.IndexOptions;
 import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.IndexableFieldType;
 import org.apache.lucene.index.Term;
-import org.apache.lucene.search.ConstantScoreQuery;
 import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TermQuery;
@@ -276,8 +275,7 @@ public abstract class NumberFieldMapper<T extends Number> extends AbstractFieldM
 
     @Override
     public final Query termQuery(Object value, @Nullable QueryParseContext context) {
-        TermQuery scoringQuery = new TermQuery(new Term(names.indexName(), indexedValueForSearch(value)));
-        return new ConstantScoreQuery(scoringQuery);
+        return new TermQuery(new Term(names.indexName(), indexedValueForSearch(value)));
     }
 
     @Override

+ 5 - 9
src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java

@@ -464,7 +464,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
     public void testTermQueryBuilder() throws IOException {
         IndexQueryParserService queryParser = queryParser();
         Query parsedQuery = queryParser.parse(termQuery("age", 34).buildAsBytes()).query();
-        TermQuery fieldQuery = unwrapTermQuery(parsedQuery, true);
+        TermQuery fieldQuery = unwrapTermQuery(parsedQuery);
         assertThat(fieldQuery.getTerm().bytes(), equalTo(indexedValueForSearch(34l)));
     }
 
@@ -472,15 +472,11 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
     public void testTermQuery() throws IOException {
         IndexQueryParserService queryParser = queryParser();
         String query = copyToStringFromClasspath("/org/elasticsearch/index/query/term.json");
-        TermQuery fieldQuery = unwrapTermQuery(queryParser.parse(query).query(), true);
+        TermQuery fieldQuery = unwrapTermQuery(queryParser.parse(query).query());
         assertThat(fieldQuery.getTerm().bytes(), equalTo(indexedValueForSearch(34l)));
     }
 
-    private static TermQuery unwrapTermQuery(Query q, boolean expectConstantWrapper) {
-        if (expectConstantWrapper) {
-            assertThat(q, instanceOf(ConstantScoreQuery.class));
-            q = ((ConstantScoreQuery) q).getQuery();
-        }
+    private static TermQuery unwrapTermQuery(Query q) {
         assertThat(q, instanceOf(TermQuery.class));
         return (TermQuery) q;
     }
@@ -545,7 +541,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
         IndexQueryParserService queryParser = queryParser();
 
         Query parsedQuery = queryParser.parse(termQuery("age", 34).boost(2.0f)).query();
-        TermQuery fieldQuery = unwrapTermQuery(parsedQuery, true);
+        TermQuery fieldQuery = unwrapTermQuery(parsedQuery);
         assertThat(fieldQuery.getTerm().bytes(), equalTo(indexedValueForSearch(34l)));
         assertThat((double) parsedQuery.getBoost(), closeTo(2.0, 0.01));
     }
@@ -563,7 +559,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest {
         IndexQueryParserService queryParser = queryParser();
         String query = copyToStringFromClasspath("/org/elasticsearch/index/query/term-with-boost.json");
         Query parsedQuery = queryParser.parse(query).query();
-        TermQuery fieldQuery = unwrapTermQuery(parsedQuery, true);
+        TermQuery fieldQuery = unwrapTermQuery(parsedQuery);
         assertThat(fieldQuery.getTerm().bytes(), equalTo(indexedValueForSearch(34l)));
         assertThat((double) parsedQuery.getBoost(), closeTo(2.0, 0.01));
     }