You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2014/01/08 15:26:15 UTC

svn commit: r1556546 - in /lucene/dev/branches/lucene5376/lucene/server/src: java/org/apache/lucene/server/handlers/SearchHandler.java test/org/apache/lucene/server/TestVirtualFields.java

Author: mikemccand
Date: Wed Jan  8 14:26:14 2014
New Revision: 1556546

URL: http://svn.apache.org/r1556546
Log:
LUCENE-5376: turn on scoring when sorting by field if any of the sort fields or retrieved fields require scores, e.g. when they are an expression field that uses _score

Modified:
    lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/SearchHandler.java
    lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestVirtualFields.java

Modified: lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/SearchHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/SearchHandler.java?rev=1556546&r1=1556545&r2=1556546&view=diff
==============================================================================
--- lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/SearchHandler.java (original)
+++ lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/SearchHandler.java Wed Jan  8 14:26:14 2014
@@ -740,13 +740,9 @@ public class SearchHandler extends Handl
           AtomicReaderContext leaf = leaves.get(ReaderUtil.subIndex(hit.doc, leaves));
           Map<String,Object> context = new HashMap<String,Object>();
 
-          // nocommit: should we only do this if "wantsScores"?
-          // where do we get that boolean!!
           int docID = hit.doc - leaf.docBase;
 
-          // nocommit not quite right?  what if app didn't
-          // sort by score but uses it in the expr that it
-          // is sorting by?
+          assert Float.isNaN(hit.score) == false || fd.valueSource.getSortField(false).needsScores() == false;
           context.put("scorer", new CannedScorer(docID, hit.score));
           FunctionValues segValues = fd.valueSource.getValues(context, leaf);
           result.put(name, segValues.doubleVal(docID));
@@ -1721,6 +1717,8 @@ public class SearchHandler extends Handl
     final Set<String> fields;
     final Map<String,FieldHighlightConfig> highlightFields;
 
+    boolean forceDocScores = false;
+
     if (r.hasParam("retrieveFields")) {
       fields = new HashSet<String>();
       highlightFields = new HashMap<String,FieldHighlightConfig>();
@@ -1769,6 +1767,14 @@ public class SearchHandler extends Handl
           // Dead code but compiler disagrees:
           fd = null;
         }
+
+        // If any of the fields being retrieved require
+        // score, than force returned FieldDoc.score to be
+        // computed:
+        if (fd.valueSource != null && fd.valueSource.getSortField(false).needsScores()) {
+          forceDocScores = true;
+        }
+
         if (perField != null) {
           perField.multiValued = fd.multiValued;
           if (fd.multiValued == false && perField.mode.equals("joinedSnippets")) {
@@ -1902,6 +1908,13 @@ public class SearchHandler extends Handl
         //c = TopScoreDocCollector.create(topHits, searchAfter, !w.scoresDocsOutOfOrder());
         c = TopScoreDocCollector.create(topHits, searchAfter, false);
       } else {
+
+        // If any of the sort fields require score, than
+        // ask for FieldDoc.score in the returned hits:
+        for(SortField sortField : sort.getSort()) {
+          forceDocScores |= sortField.needsScores();
+        }
+
         // Sort by fields:
         FieldDoc searchAfter;
         if (r.hasParam("searchAfter")) {
@@ -1916,7 +1929,7 @@ public class SearchHandler extends Handl
 
         //c = TopFieldCollector.create(sort, topHits, searchAfter, true, doDocScores, doMaxScore, !w.scoresDocsOutOfOrder());
         c = TopFieldCollector.create(sort, topHits, searchAfter, true,
-                                     sortRequest.getBoolean("doDocScores"),
+                                     sortRequest.getBoolean("doDocScores") || forceDocScores,
                                      sortRequest.getBoolean("doMaxScore"),
                                      false);
       }

Modified: lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestVirtualFields.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestVirtualFields.java?rev=1556546&r1=1556545&r2=1556546&view=diff
==============================================================================
--- lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestVirtualFields.java (original)
+++ lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestVirtualFields.java Wed Jan  8 14:26:14 2014
@@ -108,7 +108,7 @@ public class TestVirtualFields extends S
     assertEquals(0.0f, getFloat(result, "hits[1].fields.logboost"), .0001f);
   }
 
-  public void testWithScore() throws Exception {
+  public void testWithScore1() throws Exception {
     deleteAllDocs();
     send("addDocument", "{fields: {text: 'the wind is howling like this swirling storm inside', id: 0, boost: 1.0}}");
     long gen = getLong(send("addDocument", "{fields: {text: 'I am one with the wind and sky', id: 1, boost: 2.0}}"), "indexGen");
@@ -122,8 +122,6 @@ public class TestVirtualFields extends S
   }
 
   /** Also tries to retrieve the scoreboost */
-  // nocommit fixme: it currently fails because of NaN disaster
-  /*
   public void testWithScore2() throws Exception {
     deleteAllDocs();
     send("addDocument", "{fields: {text: 'the wind is howling like this swirling storm inside', id: 0, boost: 1.0}}");
@@ -139,7 +137,24 @@ public class TestVirtualFields extends S
     assertEquals(.6931f, getFloat(result, "hits[0].fields.logboost"), .0001f);
     assertEquals(0.0f, getFloat(result, "hits[1].fields.logboost"), .0001f);
   }
-  */
+
+  /** Sort by not score, and try to retrieve expression
+   *  using score. */
+  public void testWithScore3() throws Exception {
+    deleteAllDocs();
+    send("addDocument", "{fields: {text: 'the wind is howling like this swirling storm inside', id: 0, boost: 1.0}}");
+    long gen = getLong(send("addDocument", "{fields: {text: 'I am one with the wind and sky', id: 1, boost: 2.0}}"), "indexGen");
+    JSONObject result = send("search", "{queryText: wind, sort: {fields: [{field: id, reverse: true}]}, retrieveFields: [id, scoreboost, logboost], searcher: {indexGen: " + gen + "}}");
+    assertEquals(2, getInt(result, "totalHits"));
+    assertEquals(1, getInt(result, "hits[0].fields.id"));
+    assertEquals(0, getInt(result, "hits[1].fields.id"));
+
+    assertEquals(.80361f, getFloat(result, "hits[0].fields.scoreboost"), .0001f);
+    assertEquals(.11046f, getFloat(result, "hits[1].fields.scoreboost"), .0001f);
+
+    assertEquals(.6931f, getFloat(result, "hits[0].fields.logboost"), .0001f);
+    assertEquals(0.0f, getFloat(result, "hits[1].fields.logboost"), .0001f);
+  }
 
   public void testSyntaxError() throws Exception {
     deleteAllDocs();