You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ro...@apache.org on 2020/04/24 11:08:28 UTC

[lucene-solr] branch master updated: LUCENE-9340: Deprecate SimpleBindings#add(SortField) (#1447)

This is an automated email from the ASF dual-hosted git repository.

romseygeek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/master by this push:
     new f6462ee  LUCENE-9340: Deprecate SimpleBindings#add(SortField) (#1447)
f6462ee is described below

commit f6462ee35056f92bcfeed5f251d5372506e66b57
Author: Alan Woodward <ro...@apache.org>
AuthorDate: Fri Apr 24 12:08:16 2020 +0100

    LUCENE-9340: Deprecate SimpleBindings#add(SortField) (#1447)
    
    This method is trappy; it doesn't work for all SortField types, but doesn't tell
    you that until runtime. This commit deprecates it, and removes all other
    callsites in the codebase.
---
 lucene/CHANGES.txt                                 |  2 ++
 .../lucene/demo/facet/DistanceFacetsExample.java   |  5 ++-
 .../facet/ExpressionAggregationFacetsExample.java  |  6 ++--
 .../apache/lucene/expressions/SimpleBindings.java  | 22 +++++++------
 .../lucene/expressions/TestDemoExpressions.java    | 37 +++++++++++-----------
 .../lucene/expressions/TestExpressionRescorer.java |  6 ++--
 .../expressions/TestExpressionSortField.java       | 21 ++++++------
 .../lucene/expressions/TestExpressionSorts.java    | 20 +++++++++++-
 .../expressions/TestExpressionValidation.java      | 14 ++++----
 .../expressions/TestExpressionValueSource.java     | 17 +++++-----
 .../DocumentExpressionDictionaryFactory.java       | 20 +++++++++++-
 .../apache/solr/schema/WrappedIntPointField.java   | 20 +++++++++++-
 12 files changed, 124 insertions(+), 66 deletions(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index db5d42a..b801241 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -131,6 +131,8 @@ API Changes
 * LUCENE-9339: MergeScheduler#merge doesn't accept a parameter if a new merge was found anymore.
   (Simon Willnauer)
 
+* LUCENE-9340: Deprecate SimpleBindings#add(SortField). (Alan Woodward)
+
 New Features
 ---------------------
 (No changes)
diff --git a/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java b/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java
index 2b9b485..6f89c41 100644
--- a/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java
+++ b/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java
@@ -46,7 +46,6 @@ import org.apache.lucene.search.DoubleValuesSource;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.store.ByteBuffersDirectory;
 import org.apache.lucene.store.Directory;
@@ -126,8 +125,8 @@ public class DistanceFacetsExample implements Closeable {
       throw new RuntimeException(pe);
     }
     SimpleBindings bindings = new SimpleBindings();
-    bindings.add(new SortField("latitude", SortField.Type.DOUBLE));
-    bindings.add(new SortField("longitude", SortField.Type.DOUBLE));
+    bindings.add("latitude", DoubleValuesSource.fromDoubleField("latitude"));
+    bindings.add("longitude", DoubleValuesSource.fromDoubleField("longitude"));
 
     return distance.getDoubleValuesSource(bindings);
   }
diff --git a/lucene/demo/src/java/org/apache/lucene/demo/facet/ExpressionAggregationFacetsExample.java b/lucene/demo/src/java/org/apache/lucene/demo/facet/ExpressionAggregationFacetsExample.java
index 7363e7d..fdcdfb0 100644
--- a/lucene/demo/src/java/org/apache/lucene/demo/facet/ExpressionAggregationFacetsExample.java
+++ b/lucene/demo/src/java/org/apache/lucene/demo/facet/ExpressionAggregationFacetsExample.java
@@ -40,9 +40,9 @@ import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
+import org.apache.lucene.search.DoubleValuesSource;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
-import org.apache.lucene.search.SortField;
 import org.apache.lucene.store.ByteBuffersDirectory;
 import org.apache.lucene.store.Directory;
 
@@ -91,8 +91,8 @@ public class ExpressionAggregationFacetsExample {
     // and its popularity field
     Expression expr = JavascriptCompiler.compile("_score * sqrt(popularity)");
     SimpleBindings bindings = new SimpleBindings();
-    bindings.add(new SortField("_score", SortField.Type.SCORE)); // the score of the document
-    bindings.add(new SortField("popularity", SortField.Type.LONG)); // the value of the 'popularity' field
+    bindings.add("_score", DoubleValuesSource.SCORES); // the score of the document
+    bindings.add("popularity", DoubleValuesSource.fromLongField("popularity")); // the value of the 'popularity' field
 
     // Aggregates the facet values
     FacetsCollector fc = new FacetsCollector(true);
diff --git a/lucene/expressions/src/java/org/apache/lucene/expressions/SimpleBindings.java b/lucene/expressions/src/java/org/apache/lucene/expressions/SimpleBindings.java
index 3b2362b..1b8e065 100644
--- a/lucene/expressions/src/java/org/apache/lucene/expressions/SimpleBindings.java
+++ b/lucene/expressions/src/java/org/apache/lucene/expressions/SimpleBindings.java
@@ -27,16 +27,16 @@ import org.apache.lucene.search.DoubleValuesSource;
 import org.apache.lucene.search.SortField;
 
 /**
- * Simple class that binds expression variable names to {@link SortField}s
+ * Simple class that binds expression variable names to {@link DoubleValuesSource}s
  * or other {@link Expression}s.
  * <p>
  * Example usage:
  * <pre class="prettyprint">
  *   SimpleBindings bindings = new SimpleBindings();
  *   // document's text relevance score
- *   bindings.add(new SortField("_score", SortField.Type.SCORE));
+ *   bindings.add("_score", DoubleValuesSource.SCORES);
  *   // integer NumericDocValues field
- *   bindings.add(new SortField("popularity", SortField.Type.INT));
+ *   bindings.add("popularity", DoubleValuesSource.fromIntField("popularity"));
  *   // another expression
  *   bindings.add("recency", myRecencyExpression);
  *   
@@ -48,17 +48,21 @@ import org.apache.lucene.search.SortField;
  */
 public final class SimpleBindings extends Bindings {
 
-  final Map<String, Function<Bindings, DoubleValuesSource>> map = new HashMap<>();
-  
+  private final Map<String, Function<Bindings, DoubleValuesSource>> map = new HashMap<>();
+
   /** Creates a new empty Bindings */
   public SimpleBindings() {}
   
   /** 
    * Adds a SortField to the bindings.
-   * <p>
-   * This can be used to reference a DocValuesField, a field from
-   * FieldCache, the document's score, etc. 
+   *
+   * @see DoubleValuesSource#fromIntField(String)
+   * @see DoubleValuesSource#fromLongField(String)
+   * @see DoubleValuesSource#fromFloatField(String)
+   * @see DoubleValuesSource#fromDoubleField(String)
+   * @see DoubleValuesSource#SCORES
    */
+  @Deprecated
   public void add(SortField sortField) {
     map.put(sortField.getField(), bindings -> fromSortField(sortField));
   }
@@ -67,7 +71,7 @@ public final class SimpleBindings extends Bindings {
    * Bind a {@link DoubleValuesSource} directly to the given name.
    */
   public void add(String name, DoubleValuesSource source) { map.put(name, bindings -> source); }
-  
+
   /** 
    * Adds an Expression to the bindings.
    * <p>
diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestDemoExpressions.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestDemoExpressions.java
index 5edd3ee..e1188d5 100644
--- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestDemoExpressions.java
+++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestDemoExpressions.java
@@ -30,7 +30,6 @@ import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Sort;
-import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TopFieldDocs;
 import org.apache.lucene.store.Directory;
@@ -95,10 +94,10 @@ public class  TestDemoExpressions extends LuceneTestCase {
     Expression expr = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)");
     
     // we use SimpleBindings: which just maps variables to SortField instances
-    SimpleBindings bindings = new SimpleBindings();    
-    bindings.add(new SortField("_score", SortField.Type.SCORE));
-    bindings.add(new SortField("popularity", SortField.Type.INT));
-    
+    SimpleBindings bindings = new SimpleBindings();
+    bindings.add("_score", DoubleValuesSource.SCORES);
+    bindings.add("popularity", DoubleValuesSource.fromIntField("popularity"));
+
     // create a sort field and sort by it (reverse order)
     Sort sort = new Sort(expr.getSortField(bindings, true));
     Query query = new TermQuery(new Term("body", "contents"));
@@ -109,9 +108,9 @@ public class  TestDemoExpressions extends LuceneTestCase {
   public void testSortValues() throws Exception {
     Expression expr = JavascriptCompiler.compile("sqrt(_score)");
     
-    SimpleBindings bindings = new SimpleBindings();    
-    bindings.add(new SortField("_score", SortField.Type.SCORE));
-    
+    SimpleBindings bindings = new SimpleBindings();
+    bindings.add("_score", DoubleValuesSource.SCORES);
+
     Sort sort = new Sort(expr.getSortField(bindings, true));
     Query query = new TermQuery(new Term("body", "contents"));
     TopFieldDocs td = searcher.search(query, 3, sort, true);
@@ -127,8 +126,8 @@ public class  TestDemoExpressions extends LuceneTestCase {
   public void testTwoOfSameBinding() throws Exception {
     Expression expr = JavascriptCompiler.compile("_score + _score");
     
-    SimpleBindings bindings = new SimpleBindings();    
-    bindings.add(new SortField("_score", SortField.Type.SCORE));
+    SimpleBindings bindings = new SimpleBindings();
+    bindings.add("_score", DoubleValuesSource.SCORES);
     
     Sort sort = new Sort(expr.getSortField(bindings, true));
     Query query = new TermQuery(new Term("body", "contents"));
@@ -145,10 +144,10 @@ public class  TestDemoExpressions extends LuceneTestCase {
   public void testDollarVariable() throws Exception {
     Expression expr = JavascriptCompiler.compile("$0+$score");
     
-    SimpleBindings bindings = new SimpleBindings();    
-    bindings.add(new SortField("$0", SortField.Type.SCORE));
-    bindings.add(new SortField("$score", SortField.Type.SCORE));
-    
+    SimpleBindings bindings = new SimpleBindings();
+    bindings.add("$0", DoubleValuesSource.SCORES);
+    bindings.add("$score", DoubleValuesSource.SCORES);
+
     Sort sort = new Sort(expr.getSortField(bindings, true));
     Query query = new TermQuery(new Term("body", "contents"));
     TopFieldDocs td = searcher.search(query, 3, sort, true);
@@ -165,8 +164,8 @@ public class  TestDemoExpressions extends LuceneTestCase {
     Expression expr1 = JavascriptCompiler.compile("_score");
     Expression expr2 = JavascriptCompiler.compile("2*expr1");
     
-    SimpleBindings bindings = new SimpleBindings();    
-    bindings.add(new SortField("_score", SortField.Type.SCORE));
+    SimpleBindings bindings = new SimpleBindings();
+    bindings.add("_score", DoubleValuesSource.SCORES);
     bindings.add("expr1", expr1);
     
     Sort sort = new Sort(expr2.getSortField(bindings, true));
@@ -197,7 +196,7 @@ public class  TestDemoExpressions extends LuceneTestCase {
         sb.append("+");
       }
       sb.append("x" + i);
-      bindings.add(new SortField("x" + i, SortField.Type.SCORE));
+      bindings.add("x" + i, DoubleValuesSource.SCORES);
     }
     
     Expression expr = JavascriptCompiler.compile(sb.toString());
@@ -215,8 +214,8 @@ public class  TestDemoExpressions extends LuceneTestCase {
   public void testDistanceSort() throws Exception {
     Expression distance = JavascriptCompiler.compile("haversin(40.7143528,-74.0059731,latitude,longitude)");
     SimpleBindings bindings = new SimpleBindings();
-    bindings.add(new SortField("latitude", SortField.Type.DOUBLE));
-    bindings.add(new SortField("longitude", SortField.Type.DOUBLE));
+    bindings.add("latitude", DoubleValuesSource.fromDoubleField("latitude"));
+    bindings.add("longitude", DoubleValuesSource.fromDoubleField("longitude"));
     Sort sort = new Sort(distance.getSortField(bindings, false));
     TopFieldDocs td = searcher.search(new MatchAllDocsQuery(), 3, sort);
     
diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionRescorer.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionRescorer.java
index 37f775c..4c4d31e 100644
--- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionRescorer.java
+++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionRescorer.java
@@ -25,10 +25,10 @@ import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.search.DoubleValuesSource;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Rescorer;
-import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.search.similarities.ClassicSimilarity;
@@ -95,8 +95,8 @@ public class TestExpressionRescorer extends LuceneTestCase {
 
     Expression e = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)");
     SimpleBindings bindings = new SimpleBindings();
-    bindings.add(new SortField("popularity", SortField.Type.INT));
-    bindings.add(new SortField("_score", SortField.Type.SCORE));
+    bindings.add("popularity", DoubleValuesSource.fromIntField("popularity"));
+    bindings.add("_score", DoubleValuesSource.SCORES);
     Rescorer rescorer = e.getRescorer(bindings);
 
     hits = rescorer.rescore(searcher, hits, 10);
diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSortField.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSortField.java
index 73e7b8b..513d6a5 100644
--- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSortField.java
+++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSortField.java
@@ -18,6 +18,7 @@ package org.apache.lucene.expressions;
 
 
 import org.apache.lucene.expressions.js.JavascriptCompiler;
+import org.apache.lucene.search.DoubleValuesSource;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.util.LuceneTestCase;
 
@@ -27,8 +28,8 @@ public class TestExpressionSortField extends LuceneTestCase {
     Expression expr = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)");
     
     SimpleBindings bindings = new SimpleBindings();    
-    bindings.add(new SortField("_score", SortField.Type.SCORE));
-    bindings.add(new SortField("popularity", SortField.Type.INT));
+    bindings.add("_score", DoubleValuesSource.SCORES);
+    bindings.add("popularity", DoubleValuesSource.fromIntField("popularity"));
     
     SortField sf = expr.getSortField(bindings, true);
     assertEquals("<expr(sqrt(_score) + ln(popularity))>!", sf.toString());
@@ -38,13 +39,13 @@ public class TestExpressionSortField extends LuceneTestCase {
     Expression expr = JavascriptCompiler.compile("sqrt(_score) + ln(popularity)");
     
     SimpleBindings bindings = new SimpleBindings();    
-    bindings.add(new SortField("_score", SortField.Type.SCORE));
-    bindings.add(new SortField("popularity", SortField.Type.INT));
+    bindings.add("_score", DoubleValuesSource.SCORES);
+    bindings.add("popularity", DoubleValuesSource.fromIntField("popularity"));
     
     SimpleBindings otherBindings = new SimpleBindings();
-    otherBindings.add(new SortField("_score", SortField.Type.LONG));
-    otherBindings.add(new SortField("popularity", SortField.Type.INT));
-    
+    otherBindings.add("_score", DoubleValuesSource.fromLongField("_score"));
+    otherBindings.add("popularity", DoubleValuesSource.fromIntField("popularity"));
+
     SortField sf1 = expr.getSortField(bindings, true);
     
     // different order
@@ -90,9 +91,9 @@ public class TestExpressionSortField extends LuceneTestCase {
     Expression exprH = JavascriptCompiler.compile("b / c + e * g - sqrt(f)");
     // several variables
     Expression exprI = JavascriptCompiler.compile("b / c + e * g");
-    
-    bindings.add(new SortField("_score", SortField.Type.SCORE));
-    bindings.add(new SortField("intfield", SortField.Type.INT));
+
+    bindings.add("_score", DoubleValuesSource.SCORES);
+    bindings.add("intfield", DoubleValuesSource.fromIntField("intfield"));
     bindings.add("a", exprA);
     bindings.add("b", exprB);
     bindings.add("c", exprC);
diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSorts.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSorts.java
index 0e6287f..0e8359d 100644
--- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSorts.java
+++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionSorts.java
@@ -32,6 +32,7 @@ import org.apache.lucene.index.Term;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.CheckHits;
+import org.apache.lucene.search.DoubleValuesSource;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.Query;
@@ -128,7 +129,7 @@ public class TestExpressionSorts extends LuceneTestCase {
         SortField s = original[i];
         Expression expr = JavascriptCompiler.compile(s.getField());
         SimpleBindings simpleBindings = new SimpleBindings();
-        simpleBindings.add(s);
+        simpleBindings.add(s.getField(), fromSortField(s));
         boolean reverse = s.getType() == SortField.Type.SCORE || s.getReverse();
         mutated[i] = expr.getSortField(simpleBindings, reverse);
       } else {
@@ -146,5 +147,22 @@ public class TestExpressionSorts extends LuceneTestCase {
       CheckHits.checkEqual(query, expected.scoreDocs, actual.scoreDocs);
     }
   }
+
+  private DoubleValuesSource fromSortField(SortField field) {
+    switch(field.getType()) {
+      case INT:
+        return DoubleValuesSource.fromIntField(field.getField());
+      case LONG:
+        return DoubleValuesSource.fromLongField(field.getField());
+      case FLOAT:
+        return DoubleValuesSource.fromFloatField(field.getField());
+      case DOUBLE:
+        return DoubleValuesSource.fromDoubleField(field.getField());
+      case SCORE:
+        return DoubleValuesSource.SCORES;
+      default:
+        throw new UnsupportedOperationException();
+    }
+  }
 }
 
diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValidation.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValidation.java
index 56086b9..ab25e68 100644
--- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValidation.java
+++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValidation.java
@@ -18,7 +18,7 @@ package org.apache.lucene.expressions;
 
 
 import org.apache.lucene.expressions.js.JavascriptCompiler;
-import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.DoubleValuesSource;
 import org.apache.lucene.util.LuceneTestCase;
 
 /** Tests validation of bindings */
@@ -26,10 +26,10 @@ public class TestExpressionValidation extends LuceneTestCase {
 
   public void testValidExternals() throws Exception {
     SimpleBindings bindings = new SimpleBindings();
-    bindings.add(new SortField("valid0", SortField.Type.INT));
-    bindings.add(new SortField("valid1", SortField.Type.INT));
-    bindings.add(new SortField("valid2", SortField.Type.INT));
-    bindings.add(new SortField("_score", SortField.Type.SCORE));
+    bindings.add("valid0", DoubleValuesSource.fromIntField("valid0"));
+    bindings.add("valid1", DoubleValuesSource.fromIntField("valid1"));
+    bindings.add("valid2", DoubleValuesSource.fromIntField("valid2"));
+    bindings.add("_score", DoubleValuesSource.SCORES);
     bindings.add("valide0", JavascriptCompiler.compile("valid0 - valid1 + valid2 + _score"));
     bindings.validate();
     bindings.add("valide1", JavascriptCompiler.compile("valide0 + valid0"));
@@ -40,7 +40,7 @@ public class TestExpressionValidation extends LuceneTestCase {
   
   public void testInvalidExternal() throws Exception {
     SimpleBindings bindings = new SimpleBindings();
-    bindings.add(new SortField("valid", SortField.Type.INT));
+    bindings.add("valid", DoubleValuesSource.fromIntField("valid"));
     bindings.add("invalid", JavascriptCompiler.compile("badreference"));
     IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
       bindings.validate();
@@ -50,7 +50,7 @@ public class TestExpressionValidation extends LuceneTestCase {
   
   public void testInvalidExternal2() throws Exception {
     SimpleBindings bindings = new SimpleBindings();
-    bindings.add(new SortField("valid", SortField.Type.INT));
+    bindings.add("valid", DoubleValuesSource.fromIntField("valid"));
     bindings.add("invalid", JavascriptCompiler.compile("valid + badreference"));
     IllegalArgumentException expected = expectThrows(IllegalArgumentException.class, () -> {
       bindings.validate();
diff --git a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValueSource.java b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValueSource.java
index 39217d8..d5dbabe 100644
--- a/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValueSource.java
+++ b/lucene/expressions/src/test/org/apache/lucene/expressions/TestExpressionValueSource.java
@@ -28,7 +28,6 @@ import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.search.DoubleValues;
 import org.apache.lucene.search.DoubleValuesSource;
-import org.apache.lucene.search.SortField;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.LuceneTestCase;
 
@@ -78,8 +77,8 @@ public class TestExpressionValueSource extends LuceneTestCase {
   public void testDoubleValuesSourceTypes() throws Exception {
     Expression expr = JavascriptCompiler.compile("2*popularity + count");
     SimpleBindings bindings = new SimpleBindings();
-    bindings.add(new SortField("popularity", SortField.Type.LONG));
-    bindings.add(new SortField("count", SortField.Type.LONG));
+    bindings.add("popularity", DoubleValuesSource.fromLongField("popularity"));
+    bindings.add("count", DoubleValuesSource.fromLongField("count"));
     DoubleValuesSource vs = expr.getDoubleValuesSource(bindings);
 
     assertEquals(1, reader.leaves().size());
@@ -98,8 +97,8 @@ public class TestExpressionValueSource extends LuceneTestCase {
     Expression expr = JavascriptCompiler.compile("sqrt(a) + ln(b)");
 
     SimpleBindings bindings = new SimpleBindings();
-    bindings.add(new SortField("a", SortField.Type.INT));
-    bindings.add(new SortField("b", SortField.Type.INT));
+    bindings.add("a", DoubleValuesSource.fromIntField("a"));
+    bindings.add("b", DoubleValuesSource.fromIntField("b"));
 
     DoubleValuesSource vs1 = expr.getDoubleValuesSource(bindings);
     // same instance
@@ -114,14 +113,14 @@ public class TestExpressionValueSource extends LuceneTestCase {
     assertEquals(vs1, vs2);
     // equiv bindings (different instance)
     SimpleBindings bindings2 = new SimpleBindings();
-    bindings2.add(new SortField("a", SortField.Type.INT));
-    bindings2.add(new SortField("b", SortField.Type.INT));
+    bindings2.add("a", DoubleValuesSource.fromIntField("a"));
+    bindings2.add("b", DoubleValuesSource.fromIntField("b"));
     DoubleValuesSource vs3 = expr.getDoubleValuesSource(bindings2);
     assertEquals(vs1, vs3);
     // different bindings (same names, different types)
     SimpleBindings bindings3 = new SimpleBindings();
-    bindings3.add(new SortField("a", SortField.Type.LONG));
-    bindings3.add(new SortField("b", SortField.Type.FLOAT));
+    bindings3.add("a", DoubleValuesSource.fromLongField("a"));
+    bindings3.add("b", DoubleValuesSource.fromFloatField("b"));
     DoubleValuesSource vs4 = expr.getDoubleValuesSource(bindings3);
     assertFalse(vs1.equals(vs4));
   }
diff --git a/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentExpressionDictionaryFactory.java b/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentExpressionDictionaryFactory.java
index 61fdbcc..120c7ce 100644
--- a/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentExpressionDictionaryFactory.java
+++ b/solr/core/src/java/org/apache/solr/spelling/suggest/DocumentExpressionDictionaryFactory.java
@@ -23,6 +23,7 @@ import java.util.Set;
 import org.apache.lucene.expressions.Expression;
 import org.apache.lucene.expressions.SimpleBindings;
 import org.apache.lucene.expressions.js.JavascriptCompiler;
+import org.apache.lucene.search.DoubleValuesSource;
 import org.apache.lucene.search.LongValuesSource;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.spell.Dictionary;
@@ -89,10 +90,27 @@ public class DocumentExpressionDictionaryFactory extends DictionaryFactory {
     }
     SimpleBindings bindings = new SimpleBindings();
     for (SortField sortField : sortFields) {
-      bindings.add(sortField);
+      bindings.add(sortField.getField(), fromSortField(sortField));
     }
     return expression.getDoubleValuesSource(bindings).toLongValuesSource();
   }
+
+  private DoubleValuesSource fromSortField(SortField field) {
+    switch(field.getType()) {
+      case INT:
+        return DoubleValuesSource.fromIntField(field.getField());
+      case LONG:
+        return DoubleValuesSource.fromLongField(field.getField());
+      case FLOAT:
+        return DoubleValuesSource.fromFloatField(field.getField());
+      case DOUBLE:
+        return DoubleValuesSource.fromDoubleField(field.getField());
+      case SCORE:
+        return DoubleValuesSource.SCORES;
+      default:
+        throw new UnsupportedOperationException();
+    }
+  }
   
   private SortField getSortField(SolrCore core, String sortFieldName) {
     return core.getLatestSchema().getField(sortFieldName).getSortField(true);
diff --git a/solr/core/src/test/org/apache/solr/schema/WrappedIntPointField.java b/solr/core/src/test/org/apache/solr/schema/WrappedIntPointField.java
index c483e8c..db421e5 100644
--- a/solr/core/src/test/org/apache/solr/schema/WrappedIntPointField.java
+++ b/solr/core/src/test/org/apache/solr/schema/WrappedIntPointField.java
@@ -19,6 +19,7 @@ package org.apache.solr.schema;
 import org.apache.lucene.expressions.Expression;
 import org.apache.lucene.expressions.SimpleBindings;
 import org.apache.lucene.expressions.js.JavascriptCompiler;
+import org.apache.lucene.search.DoubleValuesSource;
 import org.apache.lucene.search.SortField;
 
 /**
@@ -35,7 +36,7 @@ public class WrappedIntPointField extends IntPointField {
       throw new RuntimeException("impossible?", e);
     }
     SimpleBindings bindings = new SimpleBindings();
-    bindings.add(superSort);
+    bindings.add(superSort.getField(), fromSortField(superSort));
     return expr.getSortField(bindings, superSort.getReverse());
   }
 
@@ -43,4 +44,21 @@ public class WrappedIntPointField extends IntPointField {
   public SortField getSortField(final SchemaField field, final boolean reverse) {
     return getSortField(super.getSortField(field, reverse), field);
   }
+
+  private static DoubleValuesSource fromSortField(SortField field) {
+    switch(field.getType()) {
+      case INT:
+        return DoubleValuesSource.fromIntField(field.getField());
+      case LONG:
+        return DoubleValuesSource.fromLongField(field.getField());
+      case FLOAT:
+        return DoubleValuesSource.fromFloatField(field.getField());
+      case DOUBLE:
+        return DoubleValuesSource.fromDoubleField(field.getField());
+      case SCORE:
+        return DoubleValuesSource.SCORES;
+      default:
+        throw new UnsupportedOperationException();
+    }
+  }
 }