Index: lucene/facet/src/test/org/apache/lucene/facet/search/TestDrillSideways.java =================================================================== --- lucene/facet/src/test/org/apache/lucene/facet/search/TestDrillSideways.java (revision 1453926) +++ lucene/facet/src/test/org/apache/lucene/facet/search/TestDrillSideways.java (working copy) @@ -32,6 +32,7 @@ import org.apache.lucene.document.Field; import org.apache.lucene.document.StringField; import org.apache.lucene.facet.FacetTestCase; +import org.apache.lucene.facet.FacetTestUtils; import org.apache.lucene.facet.index.FacetFields; import org.apache.lucene.facet.params.FacetIndexingParams; import org.apache.lucene.facet.params.FacetSearchParams; @@ -343,6 +344,61 @@ } } + public void testMultipleRequestsPerDim() throws Exception { + Directory dir = newDirectory(); + Directory taxoDir = newDirectory(); + writer = new RandomIndexWriter(random(), dir); + + // Writes facet ords to a separate directory from the + // main index: + taxoWriter = new DirectoryTaxonomyWriter(taxoDir, IndexWriterConfig.OpenMode.CREATE); + + // Reused across documents, to add the necessary facet + // fields: + facetFields = new FacetFields(taxoWriter); + + add("dim/a/x"); + add("dim/a/y"); + add("dim/a/z"); + add("dim/b"); + add("dim/c"); + add("dim/d"); + + // NRT open + IndexSearcher searcher = newSearcher(writer.getReader()); + writer.close(); + + //System.out.println("searcher=" + searcher); + + // NRT open + TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoWriter); + taxoWriter.close(); + + // Two requests against the same dim: + FacetSearchParams fsp = new FacetSearchParams( + new CountFacetRequest(new CategoryPath("dim"), 10), + new CountFacetRequest(new CategoryPath("dim", "a"), 10)); + + DrillDownQuery ddq = new DrillDownQuery(fsp.indexingParams, new MatchAllDocsQuery()); + ddq.add(new CategoryPath("dim", "a")); + DrillSidewaysResult r = new DrillSideways(searcher, taxoReader).search(null, ddq, 10, fsp); + + assertEquals(3, r.hits.totalHits); + assertEquals(2, r.facetResults.size()); + // Publish Date is only drill-down, and Lisa published + // one in 2012 and one in 2010: + assertEquals("dim: a=3 d=1 c=1 b=1", toString(r.facetResults.get(0))); + // Author is drill-sideways + drill-down: Lisa + // (drill-down) published twice, and Frank/Susan/Bob + // published once: + assertEquals("a (3)\n z (1)\n y (1)\n x (1)\n", FacetTestUtils.toSimpleString(r.facetResults.get(1))); + + searcher.getIndexReader().close(); + taxoReader.close(); + dir.close(); + taxoDir.close(); + } + public void testRandom() throws Exception { while (aChance == 0.0) { Index: lucene/facet/src/test/org/apache/lucene/facet/FacetTestUtils.java =================================================================== --- lucene/facet/src/test/org/apache/lucene/facet/FacetTestUtils.java (revision 1453926) +++ lucene/facet/src/test/org/apache/lucene/facet/FacetTestUtils.java (working copy) @@ -24,14 +24,14 @@ public static String toSimpleString(FacetResult fr) { StringBuilder sb = new StringBuilder(); - toSimpleString(0, sb, fr.getFacetResultNode(), ""); + toSimpleString(fr.getFacetRequest().categoryPath.length, 0, sb, fr.getFacetResultNode(), ""); return sb.toString(); } - private static void toSimpleString(int depth, StringBuilder sb, FacetResultNode node, String indent) { - sb.append(indent + node.label.components[depth] + " (" + (int) node.value + ")\n"); + private static void toSimpleString(int startLength, int depth, StringBuilder sb, FacetResultNode node, String indent) { + sb.append(indent + node.label.components[startLength+depth-1] + " (" + (int) node.value + ")\n"); for (FacetResultNode childNode : node.subResults) { - toSimpleString(depth + 1, sb, childNode, indent + " "); + toSimpleString(startLength, depth + 1, sb, childNode, indent + " "); } } Index: lucene/facet/src/java/org/apache/lucene/facet/search/DrillSideways.java =================================================================== --- lucene/facet/src/java/org/apache/lucene/facet/search/DrillSideways.java (revision 1453926) +++ lucene/facet/src/java/org/apache/lucene/facet/search/DrillSideways.java (working copy) @@ -75,6 +75,7 @@ * Search, collecting hits with a {@link Collector}, and * computing drill down and sideways counts. */ + @SuppressWarnings({"rawtypes","unchecked"}) public DrillSidewaysResult search(DrillDownQuery query, Collector hitCollector, FacetSearchParams fsp) throws IOException { @@ -131,29 +132,29 @@ int idx = 0; for(String dim : drillDownDims.keySet()) { - FacetRequest drillSidewaysRequest = null; + List requests = new ArrayList(); for(FacetRequest fr : fsp.facetRequests) { assert fr.categoryPath.length > 0; if (fr.categoryPath.components[0].equals(dim)) { - if (drillSidewaysRequest != null) { - throw new IllegalArgumentException("multiple FacetRequests for drill-sideways dimension \"" + dim + "\""); - } - drillSidewaysRequest = fr; + requests.add(fr); } } - if (drillSidewaysRequest == null) { + if (requests.isEmpty()) { throw new IllegalArgumentException("could not find FacetRequest for drill-sideways dimension \"" + dim + "\""); } - drillSidewaysCollectors[idx++] = FacetsCollector.create(getDrillSidewaysAccumulator(dim, new FacetSearchParams(fsp.indexingParams, drillSidewaysRequest))); + drillSidewaysCollectors[idx++] = FacetsCollector.create(getDrillSidewaysAccumulator(dim, new FacetSearchParams(fsp.indexingParams, requests))); } DrillSidewaysQuery dsq = new DrillSidewaysQuery(baseQuery, drillDownCollector, drillSidewaysCollectors, drillDownTerms); searcher.search(dsq, hitCollector); - List drillDownResults = drillDownCollector.getFacetResults(); + int numDims = drillDownDims.size(); + List[] drillSidewaysResults = (List[]) new List[numDims]; + List drillDownResults = null; List mergedResults = new ArrayList(); + int[] requestUpto = new int[drillDownDims.size()]; for(int i=0;i 0; @@ -161,13 +162,24 @@ if (dimIndex == null) { // Pure drill down dim (the current query didn't // drill down on this dim): + if (drillDownResults == null) { + // Lazy init, in case all requests were against + // drill-sideways dims: + drillDownResults = drillDownCollector.getFacetResults(); + } mergedResults.add(drillDownResults.get(i)); } else { // Drill sideways dim: - List sidewaysResult = drillSidewaysCollectors[dimIndex.intValue()].getFacetResults(); - - assert sidewaysResult.size() == 1: "size=" + sidewaysResult.size(); - mergedResults.add(sidewaysResult.get(0)); + int dim = dimIndex.intValue(); + List sidewaysResult = drillSidewaysResults[dim]; + if (sidewaysResult == null) { + // Lazy init, in case no facet request is against + // a given drill down dim: + sidewaysResult = drillSidewaysCollectors[dim].getFacetResults(); + drillSidewaysResults[dim] = sidewaysResult; + } + mergedResults.add(sidewaysResult.get(requestUpto[dim])); + requestUpto[dim]++; } }