You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ho...@apache.org on 2013/08/16 19:14:02 UTC

svn commit: r1514795 - in /lucene/dev/trunk/solr: CHANGES.txt core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java core/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java

Author: hossman
Date: Fri Aug 16 17:14:02 2013
New Revision: 1514795

URL: http://svn.apache.org/r1514795
Log:
SOLR-3936: Fixed QueryElevationComponent sorting when used with Grouping

Modified:
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1514795&r1=1514794&r2=1514795&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Fri Aug 16 17:14:02 2013
@@ -131,6 +131,9 @@ Bug Fixes
   of divide by zero, and makes estimated hit counts meaningful in non-optimized
   indexes.  (hossman)
   
+* SOLR-3936: Fixed QueryElevationComponent sorting when used with Grouping
+  (Michael Garski via hossman)
+
 Optimizations
 ----------------------
 

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java?rev=1514795&r1=1514794&r2=1514795&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/QueryElevationComponent.java Fri Aug 16 17:14:02 2013
@@ -44,6 +44,7 @@ import org.apache.solr.common.SolrExcept
 import org.apache.solr.common.params.QueryElevationParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.search.grouping.GroupingSpecification;
 import org.apache.solr.util.DOMUtil;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
@@ -424,23 +425,25 @@ public class QueryElevationComponent ext
         }));
       } else {
         // Check if the sort is based on score
-        boolean modify = false;
         SortField[] current = sortSpec.getSort().getSort();
-        ArrayList<SortField> sorts = new ArrayList<SortField>(current.length + 1);
-        // Perhaps force it to always sort by score
-        if (force && current[0].getType() != SortField.Type.SCORE) {
-          sorts.add(new SortField("_elevate_", comparator, true));
-          modify = true;
-        }
-        for (SortField sf : current) {
-          if (sf.getType() == SortField.Type.SCORE) {
-            sorts.add(new SortField("_elevate_", comparator, !sf.getReverse()));
-            modify = true;
-          }
-          sorts.add(sf);
+        Sort modified = this.modifySort(current, force, comparator);
+        if(modified != null) {
+          sortSpec.setSort(modified);
         }
-        if (modify) {
-          sortSpec.setSort(new Sort(sorts.toArray(new SortField[sorts.size()])));
+      }
+
+      // alter the sorting in the grouping specification if there is one
+      GroupingSpecification groupingSpec = rb.getGroupingSpec();
+      if(groupingSpec != null) {
+        SortField[] groupSort = groupingSpec.getGroupSort().getSort();
+        Sort modGroupSort = this.modifySort(groupSort, force, comparator);
+        if(modGroupSort != null) {
+          groupingSpec.setGroupSort(modGroupSort);
+        }
+        SortField[] withinGroupSort = groupingSpec.getSortWithinGroup().getSort();
+        Sort modWithinGroupSort = this.modifySort(withinGroupSort, force, comparator);
+        if(modWithinGroupSort != null) {
+          groupingSpec.setSortWithinGroup(modWithinGroupSort);
         }
       }
     }
@@ -466,6 +469,25 @@ public class QueryElevationComponent ext
     }
   }
 
+  private Sort modifySort(SortField[] current, boolean force, ElevationComparatorSource comparator) {
+    boolean modify = false;
+    ArrayList<SortField> sorts = new ArrayList<SortField>(current.length + 1);
+    // Perhaps force it to always sort by score
+    if (force && current[0].getType() != SortField.Type.SCORE) {
+      sorts.add(new SortField("_elevate_", comparator, true));
+      modify = true;
+    }
+    for (SortField sf : current) {
+      if (sf.getType() == SortField.Type.SCORE) {
+        sorts.add(new SortField("_elevate_", comparator, !sf.getReverse()));
+        modify = true;
+      }
+      sorts.add(sf);
+    }
+
+    return modify ? new Sort(sorts.toArray(new SortField[sorts.size()])) : null;
+  }
+
   @Override
   public void process(ResponseBuilder rb) throws IOException {
     // Do nothing -- the real work is modifying the input query

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java?rev=1514795&r1=1514794&r2=1514795&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java Fri Aug 16 17:14:02 2013
@@ -22,6 +22,7 @@ import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.IOUtils;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.GroupParams;
 import org.apache.solr.common.params.MapSolrParams;
 import org.apache.solr.common.params.QueryElevationParams;
 import org.apache.solr.util.FileUtils;
@@ -106,6 +107,208 @@ public class QueryElevationComponentTest
   }
 
   @Test
+  public void testGroupedQuery() throws Exception {
+    try {
+      init("schema11.xml");
+      clearIndex();
+      assertU(commit());
+      assertU(adoc("id", "1", "text", "XXXX XXXX", "str_s", "a"));
+      assertU(adoc("id", "2", "text", "XXXX AAAA", "str_s", "b"));
+      assertU(adoc("id", "3", "text", "ZZZZ", "str_s", "c"));
+      assertU(adoc("id", "4", "text", "XXXX ZZZZ", "str_s", "d"));
+      assertU(adoc("id", "5", "text", "ZZZZ ZZZZ", "str_s", "e"));
+      assertU(adoc("id", "6", "text", "AAAA AAAA AAAA", "str_s", "f"));
+      assertU(adoc("id", "7", "text", "AAAA AAAA ZZZZ", "str_s", "g"));
+      assertU(adoc("id", "8", "text", "XXXX", "str_s", "h"));
+      assertU(adoc("id", "9", "text", "YYYY ZZZZ", "str_s", "i"));
+      
+      assertU(adoc("id", "22", "text", "XXXX ZZZZ AAAA", "str_s", "b"));
+      assertU(adoc("id", "66", "text", "XXXX ZZZZ AAAA", "str_s", "f"));
+      assertU(adoc("id", "77", "text", "XXXX ZZZZ AAAA", "str_s", "g"));
+     
+      assertU(commit());
+
+      final String groups = "//arr[@name='groups']";
+
+      assertQ("non-elevated group query", 
+              req(CommonParams.Q, "AAAA", 
+                  CommonParams.QT, "/elevate",
+                  GroupParams.GROUP_FIELD, "str_s", 
+                  GroupParams.GROUP, "true",
+                  GroupParams.GROUP_TOTAL_COUNT, "true", 
+                  GroupParams.GROUP_LIMIT, "100", 
+                  QueryElevationParams.ENABLE, "false",
+                  CommonParams.FL, "id, score, [elevated]")
+              , "//*[@name='ngroups'][.='3']"
+              , "//*[@name='matches'][.='6']"
+
+              , groups +"/lst[1]//doc[1]/float[@name='id'][.='6.0']"
+              , groups +"/lst[1]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[1]//doc[2]/float[@name='id'][.='66.0']"
+              , groups +"/lst[1]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[2]//doc[1]/float[@name='id'][.='7.0']"
+              , groups +"/lst[2]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[2]//doc[2]/float[@name='id'][.='77.0']"
+              , groups +"/lst[2]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[3]//doc[1]/float[@name='id'][.='2.0']"
+              , groups +"/lst[3]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[3]//doc[2]/float[@name='id'][.='22.0']"
+              , groups +"/lst[3]//doc[2]/bool[@name='[elevated]'][.='false']"
+              );
+
+      assertQ("elevated group query", 
+              req(CommonParams.Q, "AAAA", 
+                  CommonParams.QT, "/elevate",
+                  GroupParams.GROUP_FIELD, "str_s", 
+                  GroupParams.GROUP, "true",
+                  GroupParams.GROUP_TOTAL_COUNT, "true",
+                  GroupParams.GROUP_LIMIT, "100", 
+                  CommonParams.FL, "id, score, [elevated]")
+              , "//*[@name='ngroups'][.='3']"
+              , "//*[@name='matches'][.='6']"
+
+              , groups +"/lst[1]//doc[1]/float[@name='id'][.='7.0']"
+              , groups +"/lst[1]//doc[1]/bool[@name='[elevated]'][.='true']"
+              , groups +"/lst[1]//doc[2]/float[@name='id'][.='77.0']"
+              , groups +"/lst[1]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[2]//doc[1]/float[@name='id'][.='6.0']"
+              , groups +"/lst[2]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[2]//doc[2]/float[@name='id'][.='66.0']"
+              , groups +"/lst[2]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[3]//doc[1]/float[@name='id'][.='2.0']"
+              , groups +"/lst[3]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[3]//doc[2]/float[@name='id'][.='22.0']"
+              , groups +"/lst[3]//doc[2]/bool[@name='[elevated]'][.='false']"
+              );
+
+      assertQ("non-elevated because sorted group query", 
+              req(CommonParams.Q, "AAAA", 
+                  CommonParams.QT, "/elevate",
+                  CommonParams.SORT, "id asc",
+                  GroupParams.GROUP_FIELD, "str_s", 
+                  GroupParams.GROUP, "true",
+                  GroupParams.GROUP_TOTAL_COUNT, "true", 
+                  GroupParams.GROUP_LIMIT, "100", 
+                  CommonParams.FL, "id, score, [elevated]")
+              , "//*[@name='ngroups'][.='3']"
+              , "//*[@name='matches'][.='6']"
+
+              , groups +"/lst[1]//doc[1]/float[@name='id'][.='2.0']"
+              , groups +"/lst[1]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[1]//doc[2]/float[@name='id'][.='22.0']"
+              , groups +"/lst[1]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[2]//doc[1]/float[@name='id'][.='6.0']"
+              , groups +"/lst[2]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[2]//doc[2]/float[@name='id'][.='66.0']"
+              , groups +"/lst[2]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[3]//doc[1]/float[@name='id'][.='7.0']"
+              , groups +"/lst[3]//doc[1]/bool[@name='[elevated]'][.='true']"
+              , groups +"/lst[3]//doc[2]/float[@name='id'][.='77.0']"
+              , groups +"/lst[3]//doc[2]/bool[@name='[elevated]'][.='false']"
+              );
+
+      assertQ("force-elevated sorted group query", 
+              req(CommonParams.Q, "AAAA", 
+                  CommonParams.QT, "/elevate",
+                  CommonParams.SORT, "id asc",
+                  QueryElevationParams.FORCE_ELEVATION, "true", 
+                  GroupParams.GROUP_FIELD, "str_s", 
+                  GroupParams.GROUP, "true",
+                  GroupParams.GROUP_TOTAL_COUNT, "true", 
+                  GroupParams.GROUP_LIMIT, "100", 
+                  CommonParams.FL, "id, score, [elevated]")
+              , "//*[@name='ngroups'][.='3']"
+              , "//*[@name='matches'][.='6']"
+
+              , groups +"/lst[1]//doc[1]/float[@name='id'][.='7.0']"
+              , groups +"/lst[1]//doc[1]/bool[@name='[elevated]'][.='true']"
+              , groups +"/lst[1]//doc[2]/float[@name='id'][.='77.0']"
+              , groups +"/lst[1]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[2]//doc[1]/float[@name='id'][.='2.0']"
+              , groups +"/lst[2]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[2]//doc[2]/float[@name='id'][.='22.0']"
+              , groups +"/lst[2]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[3]//doc[1]/float[@name='id'][.='6.0']"
+              , groups +"/lst[3]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[3]//doc[2]/float[@name='id'][.='66.0']"
+              , groups +"/lst[3]//doc[2]/bool[@name='[elevated]'][.='false']"
+              );
+
+
+      assertQ("non-elevated because of sort within group query", 
+              req(CommonParams.Q, "AAAA", 
+                  CommonParams.QT, "/elevate",
+                  CommonParams.SORT, "id asc",
+                  GroupParams.GROUP_SORT, "id desc", 
+                  GroupParams.GROUP_FIELD, "str_s", 
+                  GroupParams.GROUP, "true",
+                  GroupParams.GROUP_TOTAL_COUNT, "true", 
+                  GroupParams.GROUP_LIMIT, "100", 
+                  CommonParams.FL, "id, score, [elevated]")
+              , "//*[@name='ngroups'][.='3']"
+              , "//*[@name='matches'][.='6']"
+
+              , groups +"/lst[1]//doc[1]/float[@name='id'][.='22.0']"
+              , groups +"/lst[1]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[1]//doc[2]/float[@name='id'][.='2.0']"
+              , groups +"/lst[1]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[2]//doc[1]/float[@name='id'][.='66.0']"
+              , groups +"/lst[2]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[2]//doc[2]/float[@name='id'][.='6.0']"
+              , groups +"/lst[2]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[3]//doc[1]/float[@name='id'][.='77.0']"
+              , groups +"/lst[3]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[3]//doc[2]/float[@name='id'][.='7.0']"
+              , groups +"/lst[3]//doc[2]/bool[@name='[elevated]'][.='true']"
+              );
+
+
+      assertQ("force elevated sort within sorted group query", 
+              req(CommonParams.Q, "AAAA", 
+                  CommonParams.QT, "/elevate",
+                  CommonParams.SORT, "id asc",
+                  GroupParams.GROUP_SORT, "id desc", 
+                  QueryElevationParams.FORCE_ELEVATION, "true", 
+                  GroupParams.GROUP_FIELD, "str_s", 
+                  GroupParams.GROUP, "true",
+                  GroupParams.GROUP_TOTAL_COUNT, "true", 
+                  GroupParams.GROUP_LIMIT, "100", 
+                  CommonParams.FL, "id, score, [elevated]")
+              , "//*[@name='ngroups'][.='3']"
+              , "//*[@name='matches'][.='6']"
+
+              , groups +"/lst[1]//doc[1]/float[@name='id'][.='7.0']"
+              , groups +"/lst[1]//doc[1]/bool[@name='[elevated]'][.='true']"
+              , groups +"/lst[1]//doc[2]/float[@name='id'][.='77.0']"
+              , groups +"/lst[1]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[2]//doc[1]/float[@name='id'][.='22.0']"
+              , groups +"/lst[2]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[2]//doc[2]/float[@name='id'][.='2.0']"
+              , groups +"/lst[2]//doc[2]/bool[@name='[elevated]'][.='false']"
+
+              , groups +"/lst[3]//doc[1]/float[@name='id'][.='66.0']"
+              , groups +"/lst[3]//doc[1]/bool[@name='[elevated]'][.='false']"
+              , groups +"/lst[3]//doc[2]/float[@name='id'][.='6.0']"
+              , groups +"/lst[3]//doc[2]/bool[@name='[elevated]'][.='false']"
+              );
+
+    } finally {
+      delete();
+    }
+  }
+
+  @Test
   public void testTrieFieldType() throws Exception {
     try {
       init("schema.xml");