From f44831feb9dec636679bff68da85ef3ef1115063 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Sun, 16 Mar 2014 11:45:34 +0000 Subject: [PATCH] LUCENE-5525: implement MultiFacets.getAllDims git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1578042 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 4 ++ .../demo/facet/SimpleFacetsExample.java | 46 ++++++++++++++++++- .../demo/facet/TestSimpleFacetsExample.java | 8 +++- .../org/apache/lucene/facet/MultiFacets.java | 23 +++++++++- .../lucene/facet/TestDrillSideways.java | 8 +++- 5 files changed, 83 insertions(+), 6 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 5c4c1f2f7cb..dd65b690133 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -184,6 +184,10 @@ Bug fixes ArrayIndexOutOfBoundsException if a parent document had no children (Sally Ang via Mike McCandless) +* LUCENE-5525: Implement MultiFacets.getAllDims, so you can do sparse + facets through DrillSideways, for example. (Jose Peleteiro, Mike + McCandless) + Test Framework * LUCENE-5449: Rename _TestUtil and _TestHelper to remove the leading _. diff --git a/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleFacetsExample.java b/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleFacetsExample.java index 0e1c4a6cc3b..2a29c6e4fa0 100644 --- a/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleFacetsExample.java +++ b/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleFacetsExample.java @@ -24,6 +24,8 @@ import java.util.List; import org.apache.lucene.analysis.core.WhitespaceAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.facet.DrillDownQuery; +import org.apache.lucene.facet.DrillSideways.DrillSidewaysResult; +import org.apache.lucene.facet.DrillSideways; import org.apache.lucene.facet.FacetField; import org.apache.lucene.facet.FacetResult; import org.apache.lucene.facet.Facets; @@ -145,7 +147,8 @@ public class SimpleFacetsExample { return results; } - /** User drills down on 'Publish Date/2010'. */ + /** User drills down on 'Publish Date/2010', and we + * return facets for 'Author' */ private FacetResult drillDown() throws IOException { DirectoryReader indexReader = DirectoryReader.open(indexDir); IndexSearcher searcher = new IndexSearcher(indexReader); @@ -170,6 +173,33 @@ public class SimpleFacetsExample { return result; } + /** User drills down on 'Publish Date/2010', and we + * return facets for both 'Publish Date' and 'Author', + * using DrillSideways. */ + private List drillSideways() throws IOException { + DirectoryReader indexReader = DirectoryReader.open(indexDir); + IndexSearcher searcher = new IndexSearcher(indexReader); + TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir); + + // Passing no baseQuery means we drill down on all + // documents ("browse only"): + DrillDownQuery q = new DrillDownQuery(config); + + // Now user drills down on Publish Date/2010: + q.add("Publish Date", "2010"); + + DrillSideways ds = new DrillSideways(searcher, config, taxoReader); + DrillSidewaysResult result = ds.search(q, 10); + + // Retrieve results + List facets = result.facets.getAllDims(10); + + indexReader.close(); + taxoReader.close(); + + return facets; + } + /** Runs the search example. */ public List runFacetOnly() throws IOException { index(); @@ -188,6 +218,12 @@ public class SimpleFacetsExample { return drillDown(); } + /** Runs the drill-sideways example. */ + public List runDrillSideways() throws IOException { + index(); + return drillSideways(); + } + /** Runs the search and drill-down examples and prints the results. */ public static void main(String[] args) throws Exception { System.out.println("Facet counting example:"); @@ -204,11 +240,17 @@ public class SimpleFacetsExample { System.out.println("Author: " + results.get(0)); System.out.println("Publish Date: " + results.get(1)); - System.out.println("\n"); System.out.println("Facet drill-down example (Publish Date/2010):"); System.out.println("---------------------------------------------"); System.out.println("Author: " + example.runDrillDown()); + + System.out.println("\n"); + System.out.println("Facet drill-sideways example (Publish Date/2010):"); + System.out.println("---------------------------------------------"); + for(FacetResult result : example.runDrillSideways()) { + System.out.println(result); + } } } \ No newline at end of file diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java index 71804d9a322..cddd42c9e96 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java @@ -20,7 +20,6 @@ package org.apache.lucene.demo.facet; import java.util.List; import org.apache.lucene.facet.FacetResult; -import org.apache.lucene.facet.taxonomy.FacetLabel; import org.apache.lucene.util.LuceneTestCase; import org.junit.Test; @@ -48,4 +47,11 @@ public class TestSimpleFacetsExample extends LuceneTestCase { FacetResult result = new SimpleFacetsExample().runDrillDown(); assertEquals("dim=Author path=[] value=2 childCount=2\n Bob (1)\n Lisa (1)\n", result.toString()); } + + @Test + public void testDrillSideways() throws Exception { + List result = new SimpleFacetsExample().runDrillSideways(); + assertEquals("dim=Publish Date path=[] value=5 childCount=3\n 2010 (2)\n 2012 (2)\n 1999 (1)\n", result.get(0).toString()); + assertEquals("dim=Author path=[] value=2 childCount=2\n Bob (1)\n Lisa (1)\n", result.get(1).toString()); + } } diff --git a/lucene/facet/src/java/org/apache/lucene/facet/MultiFacets.java b/lucene/facet/src/java/org/apache/lucene/facet/MultiFacets.java index 00cead255fb..e5a764c0af1 100644 --- a/lucene/facet/src/java/org/apache/lucene/facet/MultiFacets.java +++ b/lucene/facet/src/java/org/apache/lucene/facet/MultiFacets.java @@ -18,6 +18,7 @@ package org.apache.lucene.facet; */ import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -65,7 +66,25 @@ public class MultiFacets extends Facets { @Override public List getAllDims(int topN) throws IOException { - // TODO - throw new UnsupportedOperationException(); + + List results = new ArrayList(); + + // First add the specific dim's facets: + for(Map.Entry ent : dimToFacets.entrySet()) { + results.add(ent.getValue().getTopChildren(topN, ent.getKey())); + } + + if (defaultFacets != null) { + + // Then add all default facets as long as we didn't + // already add that dim: + for(FacetResult result : defaultFacets.getAllDims(topN)) { + if (dimToFacets.containsKey(result.dim) == false) { + results.add(result); + } + } + } + + return results; } } diff --git a/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java b/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java index 5850ee5321b..a6875cba714 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java @@ -148,7 +148,7 @@ public class TestDrillSideways extends FacetTestCase { // published once: assertEquals("dim=Author path=[] value=5 childCount=4\n Lisa (2)\n Bob (1)\n Susan (1)\n Frank (1)\n", r.facets.getTopChildren(10, "Author").toString()); - // Another simple case: drill-down on on single fields + // Another simple case: drill-down on single fields // but OR of two values ddq = new DrillDownQuery(config); ddq.add("Author", "Lisa"); @@ -163,6 +163,12 @@ public class TestDrillSideways extends FacetTestCase { // published once: assertEquals("dim=Author path=[] value=5 childCount=4\n Lisa (2)\n Bob (1)\n Susan (1)\n Frank (1)\n", r.facets.getTopChildren(10, "Author").toString()); + assertTrue(r.facets instanceof MultiFacets); + List allResults = r.facets.getAllDims(10); + assertEquals(2, allResults.size()); + assertEquals("dim=Author path=[] value=5 childCount=4\n Lisa (2)\n Bob (1)\n Susan (1)\n Frank (1)\n", allResults.get(0).toString()); + assertEquals("dim=Publish Date path=[] value=3 childCount=2\n 2010 (2)\n 2012 (1)\n", allResults.get(1).toString()); + // More interesting case: drill-down on two fields ddq = new DrillDownQuery(config); ddq.add("Author", "Lisa");