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 2013/04/29 22:12:09 UTC

svn commit: r1477315 - in /lucene/dev/trunk/lucene: ./ facet/src/java/org/apache/lucene/facet/search/ facet/src/test/org/apache/lucene/facet/search/

Author: mikemccand
Date: Mon Apr 29 20:12:09 2013
New Revision: 1477315

URL: http://svn.apache.org/r1477315
Log:
LUCENE-4964: allow custom per-dimension drill-down queries

Added:
    lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysCollector.java   (with props)
Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillDownQuery.java
    lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSideways.java
    lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysQuery.java
    lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysScorer.java
    lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/search/TestDrillSideways.java

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1477315&r1=1477314&r2=1477315&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Mon Apr 29 20:12:09 2013
@@ -95,6 +95,10 @@ New Features
 * SOLR-4761: Add SimpleMergedSegmentWarmer, which just initializes terms,
   norms, docvalues, and so on. (Mark Miller, Mike McCandless, Robert Muir)
 
+* LUCENE-4964: Allow arbitrary Query for per-dimension drill-down to
+  DrillDownQuery and DrillSideways, to support future dynamic faceting
+  methods (Mike McCandless)
+
 ======================= Lucene 4.3.0 =======================
 
 Changes in backwards compatibility policy

Modified: lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillDownQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillDownQuery.java?rev=1477315&r1=1477314&r2=1477315&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillDownQuery.java (original)
+++ lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillDownQuery.java Mon Apr 29 20:12:09 2013
@@ -167,11 +167,25 @@ public final class DrillDownQuery extend
       }
       q = bq;
     }
-    drillDownDims.put(dim, drillDownDims.size());
 
-    final ConstantScoreQuery drillDownQuery = new ConstantScoreQuery(q);
+    add(dim, q);
+  }
+
+  /** Expert: add a custom drill-down subQuery.  Use this
+   *  when you have a separate way to drill-down on the
+   *  dimension than the indexed facet ordinals. */
+  public void add(String dim, Query subQuery) {
+
+    // TODO: we should use FilteredQuery?
+
+    // So scores of the drill-down query don't have an
+    // effect:
+    final ConstantScoreQuery drillDownQuery = new ConstantScoreQuery(subQuery);
     drillDownQuery.setBoost(0.0f);
+
     query.add(drillDownQuery, Occur.MUST);
+
+    drillDownDims.put(dim, drillDownDims.size());
   }
 
   @Override

Modified: lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSideways.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSideways.java?rev=1477315&r1=1477314&r2=1477315&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSideways.java (original)
+++ lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSideways.java Mon Apr 29 20:12:09 2013
@@ -26,6 +26,7 @@ import java.util.Set;
 
 import org.apache.lucene.facet.params.FacetSearchParams;
 import org.apache.lucene.facet.taxonomy.TaxonomyReader;
+import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
@@ -43,6 +44,7 @@ import org.apache.lucene.search.TermQuer
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.search.TopFieldCollector;
 import org.apache.lucene.search.TopScoreDocCollector;
+import org.apache.lucene.search.Weight;
 
 /**     
  * Computes drill down and sideways counts for the provided
@@ -149,7 +151,7 @@ public class DrillSideways {
     Map<String,Integer> drillDownDims = query.getDims();
 
     if (drillDownDims.isEmpty()) {
-      // Just do ordinary search:
+      // Just do ordinary search when there are no drill-downs:
       FacetsCollector c = FacetsCollector.create(getDrillDownAccumulator(fsp));
       searcher.search(query, MultiCollector.wrap(hitCollector, c));
       return new DrillSidewaysResult(c.getFacetResults(), null);      
@@ -171,25 +173,6 @@ public class DrillSideways {
       startClause = 1;
     }
 
-    Term[][] drillDownTerms = new Term[clauses.length-startClause][];
-    for(int i=startClause;i<clauses.length;i++) {
-      Query q = clauses[i].getQuery();
-      assert q instanceof ConstantScoreQuery;
-      q = ((ConstantScoreQuery) q).getQuery();
-      assert q instanceof TermQuery || q instanceof BooleanQuery;
-      if (q instanceof TermQuery) {
-        drillDownTerms[i-startClause] = new Term[] {((TermQuery) q).getTerm()};
-      } else {
-        BooleanQuery q2 = (BooleanQuery) q;
-        BooleanClause[] clauses2 = q2.getClauses();
-        drillDownTerms[i-startClause] = new Term[clauses2.length];
-        for(int j=0;j<clauses2.length;j++) {
-          assert clauses2[j].getQuery() instanceof TermQuery;
-          drillDownTerms[i-startClause][j] = ((TermQuery) clauses2[j].getQuery()).getTerm();
-        }
-      }
-    }
-
     FacetsCollector drillDownCollector = FacetsCollector.create(getDrillDownAccumulator(fsp));
 
     FacetsCollector[] drillSidewaysCollectors = new FacetsCollector[drillDownDims.size()];
@@ -209,9 +192,53 @@ public class DrillSideways {
       drillSidewaysCollectors[idx++] = FacetsCollector.create(getDrillSidewaysAccumulator(dim, new FacetSearchParams(fsp.indexingParams, requests)));
     }
 
-    DrillSidewaysQuery dsq = new DrillSidewaysQuery(baseQuery, drillDownCollector, drillSidewaysCollectors, drillDownTerms, scoreSubDocsAtOnce());
+    boolean useCollectorMethod = scoreSubDocsAtOnce();
 
-    searcher.search(dsq, hitCollector);
+    Term[][] drillDownTerms = null;
+
+    if (!useCollectorMethod) {
+      // Optimistic: assume subQueries of the DDQ are either
+      // TermQuery or BQ OR of TermQuery; if this is wrong
+      // then we detect it and fallback to the mome general
+      // but slower DrillSidewaysCollector:
+      drillDownTerms = new Term[clauses.length-startClause][];
+      for(int i=startClause;i<clauses.length;i++) {
+        Query q = clauses[i].getQuery();
+
+        // DrillDownQuery always wraps each subQuery in
+        // ConstantScoreQuery:
+        assert q instanceof ConstantScoreQuery;
+
+        q = ((ConstantScoreQuery) q).getQuery();
+
+        if (q instanceof TermQuery) {
+          drillDownTerms[i-startClause] = new Term[] {((TermQuery) q).getTerm()};
+        } else if (q instanceof BooleanQuery) {
+          BooleanQuery q2 = (BooleanQuery) q;
+          BooleanClause[] clauses2 = q2.getClauses();
+          drillDownTerms[i-startClause] = new Term[clauses2.length];
+          for(int j=0;j<clauses2.length;j++) {
+            if (clauses2[j].getQuery() instanceof TermQuery) {
+              drillDownTerms[i-startClause][j] = ((TermQuery) clauses2[j].getQuery()).getTerm();
+            } else {
+              useCollectorMethod = true;
+              break;
+            }
+          }
+        }
+      }
+    }
+
+    if (useCollectorMethod) {
+      // TODO: maybe we could push the "collector method"
+      // down into the optimized scorer to have a tighter
+      // integration ... and so TermQuery clauses could
+      // continue to run "optimized"
+      collectorMethod(query, baseQuery, startClause, hitCollector, drillDownCollector, drillSidewaysCollectors);
+    } else {
+      DrillSidewaysQuery dsq = new DrillSidewaysQuery(baseQuery, drillDownCollector, drillSidewaysCollectors, drillDownTerms);
+      searcher.search(dsq, hitCollector);
+    }
 
     int numDims = drillDownDims.size();
     List<FacetResult>[] drillSidewaysResults = new List[numDims];
@@ -230,7 +257,9 @@ public class DrillSideways {
           // Lazy init, in case all requests were against
           // drill-sideways dims:
           drillDownResults = drillDownCollector.getFacetResults();
+          //System.out.println("get DD results");
         }
+        //System.out.println("add dd results " + i);
         mergedResults.add(drillDownResults.get(i));
       } else {
         // Drill sideways dim:
@@ -250,6 +279,93 @@ public class DrillSideways {
     return new DrillSidewaysResult(mergedResults, null);
   }
 
+  /** Uses the more general but slower method of sideways
+   *  counting. This method allows an arbitrary subQuery to
+   *  implement the drill down for a given dimension. */
+  private void collectorMethod(DrillDownQuery ddq, Query baseQuery, int startClause, Collector hitCollector, Collector drillDownCollector, Collector[] drillSidewaysCollectors) throws IOException {
+
+    BooleanClause[] clauses = ddq.getBooleanQuery().getClauses();
+
+    Map<String,Integer> drillDownDims = ddq.getDims();
+
+    BooleanQuery topQuery = new BooleanQuery(true);
+    final DrillSidewaysCollector collector = new DrillSidewaysCollector(hitCollector, drillDownCollector, drillSidewaysCollectors,
+                                                                        drillDownDims);
+
+    // TODO: if query is already a BQ we could copy that and
+    // add clauses to it, instead of doing BQ inside BQ
+    // (should be more efficient)?  Problem is this can
+    // affect scoring (coord) ... too bad we can't disable
+    // coord on a clause by clause basis:
+    topQuery.add(baseQuery, BooleanClause.Occur.MUST);
+
+    // NOTE: in theory we could just make a single BQ, with
+    // +query a b c minShouldMatch=2, but in this case,
+    // annoyingly, BS2 wraps a sub-scorer that always
+    // returns 2 as the .freq(), not how many of the
+    // SHOULD clauses matched:
+    BooleanQuery subQuery = new BooleanQuery(true);
+
+    Query wrappedSubQuery = new QueryWrapper(subQuery,
+                                             new SetWeight() {
+                                               @Override
+                                               public void set(Weight w) {
+                                                 collector.setWeight(w, -1);
+                                               }
+                                             });
+    Query constantScoreSubQuery = new ConstantScoreQuery(wrappedSubQuery);
+
+    // Don't impact score of original query:
+    constantScoreSubQuery.setBoost(0.0f);
+
+    topQuery.add(constantScoreSubQuery, BooleanClause.Occur.MUST);
+
+    // Unfortunately this sub-BooleanQuery
+    // will never get BS1 because today BS1 only works
+    // if topScorer=true... and actually we cannot use BS1
+    // anyways because we need subDocsScoredAtOnce:
+    int dimIndex = 0;
+    for(int i=startClause;i<clauses.length;i++) {
+      Query q = clauses[i].getQuery();
+      // DrillDownQuery always wraps each subQuery in
+      // ConstantScoreQuery:
+      assert q instanceof ConstantScoreQuery;
+      q = ((ConstantScoreQuery) q).getQuery();
+
+      final int finalDimIndex = dimIndex;
+      subQuery.add(new QueryWrapper(q,
+                                    new SetWeight() {
+                                      @Override
+                                      public void set(Weight w) {
+                                        collector.setWeight(w, finalDimIndex);
+                                      }
+                                    }),
+                   BooleanClause.Occur.SHOULD);
+      dimIndex++;
+    }
+
+    // TODO: we could better optimize the "just one drill
+    // down" case w/ a separate [specialized]
+    // collector...
+    int minShouldMatch = drillDownDims.size()-1;
+    if (minShouldMatch == 0) {
+      // Must add another "fake" clause so BQ doesn't erase
+      // itself by rewriting to the single clause:
+      Query end = new MatchAllDocsQuery();
+      end.setBoost(0.0f);
+      subQuery.add(end, BooleanClause.Occur.SHOULD);
+      minShouldMatch++;
+    }
+
+    subQuery.setMinimumNumberShouldMatch(minShouldMatch);
+
+    //System.out.println("EXE " + topQuery);
+
+    // Collects against the passed-in
+    // drillDown/SidewaysCollectors as a side effect:
+    searcher.search(topQuery, collector);
+  }
+
   /**
    * Search, sorting by {@link Sort}, and computing
    * drill down and sideways counts.
@@ -327,5 +443,55 @@ public class DrillSideways {
       this.hits = hits;
     }
   }
+
+  private interface SetWeight {
+    public void set(Weight w);
+  }
+
+  /** Just records which Weight was given out for the
+   *  (possibly rewritten) Query. */
+  private static class QueryWrapper extends Query {
+    private final Query originalQuery;
+    private final SetWeight setter;
+
+    public QueryWrapper(Query originalQuery, SetWeight setter) {
+      this.originalQuery = originalQuery;
+      this.setter = setter;
+    }
+
+    @Override
+    public Weight createWeight(final IndexSearcher searcher) throws IOException {
+      Weight w = originalQuery.createWeight(searcher);
+      setter.set(w);
+      return w;
+    }
+
+    @Override
+    public Query rewrite(IndexReader reader) throws IOException {
+      Query rewritten = originalQuery.rewrite(reader);
+      if (rewritten != originalQuery) {
+        return new QueryWrapper(rewritten, setter);
+      } else {
+        return this;
+      }
+    }
+
+    @Override
+    public String toString(String s) {
+      return originalQuery.toString(s);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (!(o instanceof QueryWrapper)) return false;
+      final QueryWrapper other = (QueryWrapper) o;
+      return super.equals(o) && originalQuery.equals(other.originalQuery);
+    }
+
+    @Override
+    public int hashCode() {
+      return super.hashCode() * 31 + originalQuery.hashCode();
+    }
+  }
 }
 

Added: lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysCollector.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysCollector.java?rev=1477315&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysCollector.java (added)
+++ lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysCollector.java Mon Apr 29 20:12:09 2013
@@ -0,0 +1,174 @@
+package org.apache.lucene.facet.search;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.search.Collector;
+import org.apache.lucene.search.Scorer.ChildScorer;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
+
+/** Collector that scrutinizes each hit to determine if it
+ *  passed all constraints (a true hit) or if it missed
+ *  exactly one dimension (a near-miss, to count for
+ *  drill-sideways counts on that dimension). */
+class DrillSidewaysCollector extends Collector {
+
+  private final Collector hitCollector;
+  private final Collector drillDownCollector;
+  private final Collector[] drillSidewaysCollectors;
+  private final Scorer[] subScorers;
+  private final int exactCount;
+
+  // Maps Weight to either -1 (mainQuery) or to integer
+  // index of the dims drillDown.  We needs this when
+  // visiting the child scorers to correlate back to the
+  // right scorers:
+  private final Map<Weight,Integer> weightToIndex = new IdentityHashMap<Weight,Integer>();
+
+  private Scorer mainScorer;
+
+  public DrillSidewaysCollector(Collector hitCollector, Collector drillDownCollector, Collector[] drillSidewaysCollectors,
+                                Map<String,Integer> dims) {
+    this.hitCollector = hitCollector;
+    this.drillDownCollector = drillDownCollector;
+    this.drillSidewaysCollectors = drillSidewaysCollectors;
+    subScorers = new Scorer[dims.size()];
+
+    if (dims.size() == 1) {
+      // When we have only one dim, we insert the
+      // MatchAllDocsQuery, bringing the clause count to
+      // 2:
+      exactCount = 2;
+    } else {
+      exactCount = dims.size();
+    }
+  }
+
+  @Override
+  public void collect(int doc) throws IOException {
+    //System.out.println("collect doc=" + doc + " main.freq=" + mainScorer.freq() + " main.doc=" + mainScorer.docID() + " exactCount=" + exactCount);
+      
+    if (mainScorer == null) {
+      // This segment did not have any docs with any
+      // drill-down field & value:
+      return;
+    }
+
+    if (mainScorer.freq() == exactCount) {
+      // All sub-clauses from the drill-down filters
+      // matched, so this is a "real" hit, so we first
+      // collect in both the hitCollector and the
+      // drillDown collector:
+      //System.out.println("  hit " + drillDownCollector);
+      hitCollector.collect(doc);
+      drillDownCollector.collect(doc);
+
+      // Also collect across all drill-sideways counts so
+      // we "merge in" drill-down counts for this
+      // dimension.
+      for(int i=0;i<subScorers.length;i++) {
+        // This cannot be null, because it was a hit,
+        // meaning all drill-down dims matched, so all
+        // dims must have non-null scorers:
+        assert subScorers[i] != null;
+        int subDoc = subScorers[i].docID();
+        assert subDoc == doc;
+        drillSidewaysCollectors[i].collect(doc);
+      }
+
+    } else {
+      for(int i=0;i<subScorers.length;i++) {
+        if (subScorers[i] == null) {
+          // This segment did not have any docs with this
+          // drill-down field & value:
+          continue;
+        }
+        int subDoc = subScorers[i].docID();
+        //System.out.println("  sub: " + subDoc);
+        if (subDoc != doc) {
+          assert subDoc > doc: "subDoc=" + subDoc + " doc=" + doc;
+          drillSidewaysCollectors[i].collect(doc);
+          assert allMatchesFrom(i+1, doc);
+          break;
+        }
+      }
+    }
+  }
+
+  // Only used by assert:
+  private boolean allMatchesFrom(int startFrom, int doc) {
+    for(int i=startFrom;i<subScorers.length;i++) {
+      assert subScorers[i].docID() == doc;
+    }
+    return true;
+  }
+
+  @Override
+  public boolean acceptsDocsOutOfOrder() {
+    // We actually could accept docs out of order, but, we
+    // need to force BooleanScorer2 so that the
+    // sub-scorers are "on" each docID we are collecting:
+    return false;
+  }
+
+  @Override
+  public void setNextReader(AtomicReaderContext leaf) throws IOException {
+    hitCollector.setNextReader(leaf);
+    drillDownCollector.setNextReader(leaf);
+    for(Collector dsc : drillSidewaysCollectors) {
+      dsc.setNextReader(leaf);
+    }
+  }
+
+  void setWeight(Weight weight, int index) {
+    assert !weightToIndex.containsKey(weight);
+    weightToIndex.put(weight, index);
+  }
+
+  private void findScorers(Scorer scorer) {
+    Integer index = weightToIndex.get(scorer.getWeight());
+    if (index != null) {
+      if (index.intValue() == -1) {
+        mainScorer = scorer;
+      } else {
+        subScorers[index] = scorer;
+      }
+    }
+    for(ChildScorer child : scorer.getChildren()) {
+      findScorers(child.child);
+    }
+  }
+
+  @Override
+  public void setScorer(Scorer scorer) throws IOException {
+    mainScorer = null;
+    Arrays.fill(subScorers, null);
+    findScorers(scorer);
+    hitCollector.setScorer(scorer);
+    drillDownCollector.setScorer(scorer);
+    for(Collector dsc : drillSidewaysCollectors) {
+      dsc.setScorer(scorer);
+    }
+  }
+}

Modified: lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysQuery.java?rev=1477315&r1=1477314&r2=1477315&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysQuery.java (original)
+++ lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysQuery.java Mon Apr 29 20:12:09 2013
@@ -39,14 +39,12 @@ class DrillSidewaysQuery extends Query {
   final Collector drillDownCollector;
   final Collector[] drillSidewaysCollectors;
   final Term[][] drillDownTerms;
-  final boolean scoreSubDocsAtOnce;
 
-  DrillSidewaysQuery(Query baseQuery, Collector drillDownCollector, Collector[] drillSidewaysCollectors, Term[][] drillDownTerms, boolean scoreSubDocsAtOnce) {
+  DrillSidewaysQuery(Query baseQuery, Collector drillDownCollector, Collector[] drillSidewaysCollectors, Term[][] drillDownTerms) {
     this.baseQuery = baseQuery;
     this.drillDownCollector = drillDownCollector;
     this.drillSidewaysCollectors = drillSidewaysCollectors;
     this.drillDownTerms = drillDownTerms;
-    this.scoreSubDocsAtOnce = scoreSubDocsAtOnce;
   }
 
   @Override
@@ -67,7 +65,7 @@ class DrillSidewaysQuery extends Query {
     if (newQuery == baseQuery) {
       return this;
     } else {
-      return new DrillSidewaysQuery(newQuery, drillDownCollector, drillSidewaysCollectors, drillDownTerms, scoreSubDocsAtOnce);
+      return new DrillSidewaysQuery(newQuery, drillDownCollector, drillSidewaysCollectors, drillDownTerms);
     }
   }
   
@@ -157,7 +155,7 @@ class DrillSidewaysQuery extends Query {
 
         return new DrillSidewaysScorer(this, context,
                                        baseScorer,
-                                       drillDownCollector, dims, scoreSubDocsAtOnce);
+                                       drillDownCollector, dims);
       }
     };
   }

Modified: lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysScorer.java?rev=1477315&r1=1477314&r2=1477315&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysScorer.java (original)
+++ lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/search/DrillSidewaysScorer.java Mon Apr 29 20:12:09 2013
@@ -43,19 +43,17 @@ class DrillSidewaysScorer extends Scorer
 
   private static final int CHUNK = 2048;
   private static final int MASK = CHUNK-1;
-  private final boolean scoreSubDocsAtOnce;
 
   private int collectDocID = -1;
   private float collectScore;
 
   DrillSidewaysScorer(Weight w, AtomicReaderContext context, Scorer baseScorer, Collector drillDownCollector,
-                      DocsEnumsAndFreq[] dims, boolean scoreSubDocsAtOnce) {
+                      DocsEnumsAndFreq[] dims) {
     super(w);
     this.dims = dims;
     this.context = context;
     this.baseScorer = baseScorer;
     this.drillDownCollector = drillDownCollector;
-    this.scoreSubDocsAtOnce = scoreSubDocsAtOnce;
   }
 
   @Override
@@ -114,22 +112,15 @@ class DrillSidewaysScorer extends Scorer
     }
     */
 
-    //System.out.println("DS score " + scoreSubDocsAtOnce);
-    if (!scoreSubDocsAtOnce) {
-      if (baseQueryCost < drillDownCost/10) {
-        //System.out.println("baseAdvance");
-        doBaseAdvanceScoring(collector, docsEnums, sidewaysCollectors);
-      } else if (numDims > 1 && (dims[1].maxCost < baseQueryCost/10)) {
-        //System.out.println("drillDownAdvance");
-        doDrillDownAdvanceScoring(collector, docsEnums, sidewaysCollectors);
-      } else {
-        //System.out.println("union");
-        doUnionScoring(collector, docsEnums, sidewaysCollectors);
-      }
-    } else {
-      // TODO: we should fallback to BS2 ReqOptSum scorer here
+    if (baseQueryCost < drillDownCost/10) {
       //System.out.println("baseAdvance");
       doBaseAdvanceScoring(collector, docsEnums, sidewaysCollectors);
+    } else if (numDims > 1 && (dims[1].maxCost < baseQueryCost/10)) {
+      //System.out.println("drillDownAdvance");
+      doDrillDownAdvanceScoring(collector, docsEnums, sidewaysCollectors);
+    } else {
+      //System.out.println("union");
+      doUnionScoring(collector, docsEnums, sidewaysCollectors);
     }
   }
 

Modified: lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/search/TestDrillSideways.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/search/TestDrillSideways.java?rev=1477315&r1=1477314&r2=1477315&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/search/TestDrillSideways.java (original)
+++ lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/search/TestDrillSideways.java Mon Apr 29 20:12:09 2013
@@ -120,12 +120,14 @@ public class TestDrillSideways extends F
         new CountFacetRequest(new CategoryPath("Publish Date"), 10), 
         new CountFacetRequest(new CategoryPath("Author"), 10));
 
+    DrillSideways ds = new DrillSideways(searcher, taxoReader);
+
     // Simple case: drill-down on a single field; in this
     // case the drill-sideways + drill-down counts ==
     // drill-down of just the query: 
     DrillDownQuery ddq = new DrillDownQuery(fsp.indexingParams, new MatchAllDocsQuery());
     ddq.add(new CategoryPath("Author", "Lisa"));
-    DrillSidewaysResult r = new DrillSideways(searcher, taxoReader).search(null, ddq, 10, fsp);
+    DrillSidewaysResult r = ds.search(null, ddq, 10, fsp);
 
     assertEquals(2, r.hits.totalHits);
     assertEquals(2, r.facetResults.size());
@@ -143,7 +145,7 @@ public class TestDrillSideways extends F
     // just the query:
     ddq = new DrillDownQuery(fsp.indexingParams);
     ddq.add(new CategoryPath("Author", "Lisa"));
-    r = new DrillSideways(searcher, taxoReader).search(null, ddq, 10, fsp);
+    r = ds.search(null, ddq, 10, fsp);
 
     assertEquals(2, r.hits.totalHits);
     assertEquals(2, r.facetResults.size());
@@ -162,7 +164,7 @@ public class TestDrillSideways extends F
     // but OR of two values
     ddq = new DrillDownQuery(fsp.indexingParams, new MatchAllDocsQuery());
     ddq.add(new CategoryPath("Author", "Lisa"), new CategoryPath("Author", "Bob"));
-    r = new DrillSideways(searcher, taxoReader).search(null, ddq, 10, fsp);
+    r = ds.search(null, ddq, 10, fsp);
     assertEquals(3, r.hits.totalHits);
     assertEquals(2, r.facetResults.size());
     // Publish Date is only drill-down: Lisa and Bob
@@ -177,7 +179,7 @@ public class TestDrillSideways extends F
     ddq = new DrillDownQuery(fsp.indexingParams, new MatchAllDocsQuery());
     ddq.add(new CategoryPath("Author", "Lisa"));
     ddq.add(new CategoryPath("Publish Date", "2010"));
-    r = new DrillSideways(searcher, taxoReader).search(null, ddq, 10, fsp);
+    r = ds.search(null, ddq, 10, fsp);
     assertEquals(1, r.hits.totalHits);
     assertEquals(2, r.facetResults.size());
     // Publish Date is drill-sideways + drill-down: Lisa
@@ -195,7 +197,7 @@ public class TestDrillSideways extends F
     ddq.add(new CategoryPath("Author", "Lisa"),
             new CategoryPath("Author", "Bob"));
     ddq.add(new CategoryPath("Publish Date", "2010"));
-    r = new DrillSideways(searcher, taxoReader).search(null, ddq, 10, fsp);
+    r = ds.search(null, ddq, 10, fsp);
     assertEquals(2, r.hits.totalHits);
     assertEquals(2, r.facetResults.size());
     // Publish Date is both drill-sideways + drill-down:
@@ -211,7 +213,7 @@ public class TestDrillSideways extends F
     fsp = new FacetSearchParams(
         new CountFacetRequest(new CategoryPath("Publish Date"), 10), 
         new CountFacetRequest(new CategoryPath("Foobar"), 10));
-    r = new DrillSideways(searcher, taxoReader).search(null, ddq, 10, fsp);
+    r = ds.search(null, ddq, 10, fsp);
     assertEquals(0, r.hits.totalHits);
     assertEquals(2, r.facetResults.size());
     assertEquals("Publish Date:", toString(r.facetResults.get(0)));
@@ -224,7 +226,7 @@ public class TestDrillSideways extends F
     fsp = new FacetSearchParams(
         new CountFacetRequest(new CategoryPath("Publish Date"), 10), 
         new CountFacetRequest(new CategoryPath("Author"), 10));
-    r = new DrillSideways(searcher, taxoReader).search(null, ddq, 10, fsp);
+    r = ds.search(null, ddq, 10, fsp);
     assertEquals(2, r.hits.totalHits);
     assertEquals(2, r.facetResults.size());
     // Publish Date is only drill-down, and Lisa published
@@ -242,7 +244,7 @@ public class TestDrillSideways extends F
             new CategoryPath("Author", "Tom"));
     fsp = new FacetSearchParams(
               new CountFacetRequest(new CategoryPath("Publish Date"), 10));
-    r = new DrillSideways(searcher, taxoReader).search(null, ddq, 10, fsp);
+    r = ds.search(null, ddq, 10, fsp);
     assertEquals(2, r.hits.totalHits);
     assertEquals(1, r.facetResults.size());
     // Publish Date is only drill-down, and Lisa published
@@ -255,7 +257,7 @@ public class TestDrillSideways extends F
         new CountFacetRequest(new CategoryPath("Author"), 10));
     ddq = new DrillDownQuery(fsp.indexingParams, new TermQuery(new Term("foobar", "baz")));
     ddq.add(new CategoryPath("Author", "Lisa"));
-    r = new DrillSideways(searcher, taxoReader).search(null, ddq, 10, fsp);
+    r = ds.search(null, ddq, 10, fsp);
 
     assertEquals(0, r.hits.totalHits);
     assertEquals(2, r.facetResults.size());