diff --git a/lucene/demo/src/java/org/apache/lucene/demo/facet/AssociationsFacetsExample.java b/lucene/demo/src/java/org/apache/lucene/demo/facet/AssociationsFacetsExample.java index 1b55c426c71..696dba25953 100644 --- a/lucene/demo/src/java/org/apache/lucene/demo/facet/AssociationsFacetsExample.java +++ b/lucene/demo/src/java/org/apache/lucene/demo/facet/AssociationsFacetsExample.java @@ -1,33 +1,5 @@ package org.apache.lucene.demo.facet; -import java.io.IOException; -import java.util.List; - -import org.apache.lucene.analysis.core.WhitespaceAnalyzer; -import org.apache.lucene.document.Document; -import org.apache.lucene.facet.associations.AssociationsFacetFields; -import org.apache.lucene.facet.associations.CategoryAssociation; -import org.apache.lucene.facet.associations.CategoryAssociationsContainer; -import org.apache.lucene.facet.associations.CategoryFloatAssociation; -import org.apache.lucene.facet.associations.CategoryIntAssociation; -import org.apache.lucene.facet.associations.SumFloatAssociationFacetRequest; -import org.apache.lucene.facet.associations.SumIntAssociationFacetRequest; -import org.apache.lucene.facet.index.FacetFields; -import org.apache.lucene.facet.params.FacetSearchParams; -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetsCollector; -import org.apache.lucene.facet.taxonomy.FacetLabel; -import org.apache.lucene.facet.taxonomy.TaxonomyReader; -import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; -import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter; -import org.apache.lucene.index.DirectoryReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.MatchAllDocsQuery; -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.RAMDirectory; - /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -45,50 +17,36 @@ import org.apache.lucene.store.RAMDirectory; * limitations under the License. */ +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.lucene.analysis.core.WhitespaceAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.facet.simple.Facets; +import org.apache.lucene.facet.simple.FacetsConfig; +import org.apache.lucene.facet.simple.FloatAssociationFacetField; +import org.apache.lucene.facet.simple.IntAssociationFacetField; +import org.apache.lucene.facet.simple.SimpleFacetResult; +import org.apache.lucene.facet.simple.SimpleFacetsCollector; +import org.apache.lucene.facet.simple.TaxonomyFacetSumFloatAssociations; +import org.apache.lucene.facet.simple.TaxonomyFacetSumIntAssociations; +import org.apache.lucene.facet.taxonomy.FacetLabel; +import org.apache.lucene.facet.taxonomy.TaxonomyReader; +import org.apache.lucene.facet.taxonomy.TaxonomyWriter; +import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; +import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.RAMDirectory; + /** Shows example usage of category associations. */ public class AssociationsFacetsExample { - /** - * Categories per document, {@link #ASSOCIATIONS} hold the association value - * for each category. - */ - public static FacetLabel[][] CATEGORIES = { - // Doc #1 - { new FacetLabel("tags", "lucene") , - new FacetLabel("genre", "computing") - }, - - // Doc #2 - { new FacetLabel("tags", "lucene"), - new FacetLabel("tags", "solr"), - new FacetLabel("genre", "computing"), - new FacetLabel("genre", "software") - } - }; - - /** Association values for each category. */ - public static CategoryAssociation[][] ASSOCIATIONS = { - // Doc #1 associations - { - /* 3 occurrences for tag 'lucene' */ - new CategoryIntAssociation(3), - /* 87% confidence level of genre 'computing' */ - new CategoryFloatAssociation(0.87f) - }, - - // Doc #2 associations - { - /* 1 occurrence for tag 'lucene' */ - new CategoryIntAssociation(1), - /* 2 occurrences for tag 'solr' */ - new CategoryIntAssociation(2), - /* 75% confidence level of genre 'computing' */ - new CategoryFloatAssociation(0.75f), - /* 34% confidence level of genre 'software' */ - new CategoryFloatAssociation(0.34f), - } - }; - private final Directory indexDir = new RAMDirectory(); private final Directory taxoDir = new RAMDirectory(); @@ -97,58 +55,79 @@ public class AssociationsFacetsExample { /** Build the example index. */ private void index() throws IOException { - IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER, - new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER))); + IndexWriterConfig iwc = new IndexWriterConfig(FacetExamples.EXAMPLES_VER, + new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER)); + IndexWriter indexWriter = new IndexWriter(indexDir, iwc); // Writes facet ords to a separate directory from the main index DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir); // Reused across documents, to add the necessary facet fields - FacetFields facetFields = new AssociationsFacetFields(taxoWriter); - - for (int i = 0; i < CATEGORIES.length; i++) { - Document doc = new Document(); - CategoryAssociationsContainer associations = new CategoryAssociationsContainer(); - for (int j = 0; j < CATEGORIES[i].length; j++) { - associations.setAssociation(CATEGORIES[i][j], ASSOCIATIONS[i][j]); - } - facetFields.addFields(doc, associations); - indexWriter.addDocument(doc); - } - + FacetsConfig config = getConfig(taxoWriter); + + Document doc = new Document(); + // 3 occurrences for tag 'lucene' + doc.add(new IntAssociationFacetField(3, "tags", "lucene")); + // 87% confidence level of genre 'computing' + doc.add(new FloatAssociationFacetField(0.87f, "genre", "computing")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + // 1 occurrence for tag 'lucene' + doc.add(new IntAssociationFacetField(1, "tags", "lucene")); + // 2 occurrence for tag 'solr' + doc.add(new IntAssociationFacetField(2, "tags", "solr")); + // 75% confidence level of genre 'computing' + doc.add(new FloatAssociationFacetField(0.75f, "genre", "computing")); + // 34% confidence level of genre 'software' + doc.add(new FloatAssociationFacetField(0.34f, "genre", "software")); + indexWriter.addDocument(config.build(doc)); + indexWriter.close(); taxoWriter.close(); } + /** It's fine if taxoWriter is null (i.e., at search time) */ + private FacetsConfig getConfig(TaxonomyWriter taxoWriter) { + FacetsConfig config = new FacetsConfig(taxoWriter); + config.setMultiValued("tags", true); + config.setIndexFieldName("tags", "$tags"); + config.setMultiValued("genre", true); + config.setIndexFieldName("genre", "$genre"); + return config; + } + /** User runs a query and aggregates facets by summing their association values. */ - private List sumAssociations() throws IOException { + private List sumAssociations() throws IOException { DirectoryReader indexReader = DirectoryReader.open(indexDir); IndexSearcher searcher = new IndexSearcher(indexReader); TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir); + FacetsConfig config = getConfig(null); - FacetLabel tags = new FacetLabel("tags"); - FacetLabel genre = new FacetLabel("genre"); - FacetSearchParams fsp = new FacetSearchParams(new SumIntAssociationFacetRequest(tags, 10), - new SumFloatAssociationFacetRequest(genre, 10)); - FacetsCollector fc = FacetsCollector.create(fsp, indexReader, taxoReader); + SimpleFacetsCollector sfc = new SimpleFacetsCollector(); // MatchAllDocsQuery is for "browsing" (counts facets // for all non-deleted docs in the index); normally // you'd use a "normal" query, and use MultiCollector to // wrap collecting the "normal" hits and also facets: - searcher.search(new MatchAllDocsQuery(), fc); + searcher.search(new MatchAllDocsQuery(), sfc); + Facets tags = new TaxonomyFacetSumIntAssociations("$tags", taxoReader, config, sfc); + Facets genre = new TaxonomyFacetSumFloatAssociations("$genre", taxoReader, config, sfc); + // Retrieve results - List facetResults = fc.getFacetResults(); - + List results = new ArrayList(); + results.add(tags.getTopChildren(10, "tags")); + results.add(genre.getTopChildren(10, "genre")); + indexReader.close(); taxoReader.close(); - return facetResults; + return results; } /** Runs summing association example. */ - public List runSumAssociations() throws IOException { + public List runSumAssociations() throws IOException { index(); return sumAssociations(); } @@ -157,10 +136,8 @@ public class AssociationsFacetsExample { public static void main(String[] args) throws Exception { System.out.println("Sum associations example:"); System.out.println("-------------------------"); - List results = new AssociationsFacetsExample().runSumAssociations(); - for (FacetResult res : results) { - System.out.println(res); - } + List results = new AssociationsFacetsExample().runSumAssociations(); + System.out.println("tags: " + results.get(0)); + System.out.println("genre: " + results.get(1)); } - } diff --git a/lucene/demo/src/java/org/apache/lucene/demo/facet/ExpressionAggregationFacetsExample.java b/lucene/demo/src/java/org/apache/lucene/demo/facet/ExpressionAggregationFacetsExample.java index 434b9a92b80..f1dd58b801f 100644 --- a/lucene/demo/src/java/org/apache/lucene/demo/facet/ExpressionAggregationFacetsExample.java +++ b/lucene/demo/src/java/org/apache/lucene/demo/facet/ExpressionAggregationFacetsExample.java @@ -13,11 +13,12 @@ import org.apache.lucene.document.TextField; import org.apache.lucene.expressions.Expression; import org.apache.lucene.expressions.SimpleBindings; import org.apache.lucene.expressions.js.JavascriptCompiler; -import org.apache.lucene.facet.index.FacetFields; -import org.apache.lucene.facet.params.FacetSearchParams; -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetsCollector; -import org.apache.lucene.facet.search.SumValueSourceFacetRequest; +import org.apache.lucene.facet.simple.FacetField; +import org.apache.lucene.facet.simple.Facets; +import org.apache.lucene.facet.simple.FacetsConfig; +import org.apache.lucene.facet.simple.SimpleFacetResult; +import org.apache.lucene.facet.simple.SimpleFacetsCollector; +import org.apache.lucene.facet.simple.TaxonomyFacetSumValueSource; import org.apache.lucene.facet.taxonomy.FacetLabel; import org.apache.lucene.facet.taxonomy.TaxonomyReader; import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; @@ -57,14 +58,6 @@ public class ExpressionAggregationFacetsExample { /** Empty constructor */ public ExpressionAggregationFacetsExample() {} - private void add(IndexWriter indexWriter, FacetFields facetFields, String text, String category, long popularity) throws IOException { - Document doc = new Document(); - doc.add(new TextField("c", text, Store.NO)); - doc.add(new NumericDocValuesField("popularity", popularity)); - facetFields.addFields(doc, Collections.singletonList(new FacetLabel(category, '/'))); - indexWriter.addDocument(doc); - } - /** Build the example index. */ private void index() throws IOException { IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER, @@ -74,20 +67,30 @@ public class ExpressionAggregationFacetsExample { DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir); // Reused across documents, to add the necessary facet fields - FacetFields facetFields = new FacetFields(taxoWriter); + FacetsConfig config = new FacetsConfig(taxoWriter); - add(indexWriter, facetFields, "foo bar", "A/B", 5L); - add(indexWriter, facetFields, "foo foo bar", "A/C", 3L); + Document doc = new Document(); + doc.add(new TextField("c", "foo bar", Store.NO)); + doc.add(new NumericDocValuesField("popularity", 5L)); + doc.add(new FacetField("A", "B")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + doc.add(new TextField("c", "foo foo bar", Store.NO)); + doc.add(new NumericDocValuesField("popularity", 3L)); + doc.add(new FacetField("A", "C")); + indexWriter.addDocument(config.build(doc)); indexWriter.close(); taxoWriter.close(); } /** User runs a query and aggregates facets. */ - private List search() throws IOException, ParseException { + private SimpleFacetResult search() throws IOException, ParseException { DirectoryReader indexReader = DirectoryReader.open(indexDir); IndexSearcher searcher = new IndexSearcher(indexReader); TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir); + FacetsConfig config = new FacetsConfig(); // Aggregate categories by an expression that combines the document's score // and its popularity field @@ -96,29 +99,27 @@ public class ExpressionAggregationFacetsExample { bindings.add(new SortField("_score", SortField.Type.SCORE)); // the score of the document bindings.add(new SortField("popularity", SortField.Type.LONG)); // the value of the 'popularity' field - FacetSearchParams fsp = new FacetSearchParams( - new SumValueSourceFacetRequest(new FacetLabel("A"), 10, expr.getValueSource(bindings), true)); - // Aggregates the facet values - FacetsCollector fc = FacetsCollector.create(fsp, searcher.getIndexReader(), taxoReader); + SimpleFacetsCollector sfc = new SimpleFacetsCollector(true); // MatchAllDocsQuery is for "browsing" (counts facets // for all non-deleted docs in the index); normally // you'd use a "normal" query, and use MultiCollector to // wrap collecting the "normal" hits and also facets: - searcher.search(new MatchAllDocsQuery(), fc); + searcher.search(new MatchAllDocsQuery(), sfc); // Retrieve results - List facetResults = fc.getFacetResults(); + Facets facets = new TaxonomyFacetSumValueSource(taxoReader, config, sfc, expr.getValueSource(bindings)); + SimpleFacetResult result = facets.getTopChildren(10, "A"); indexReader.close(); taxoReader.close(); - return facetResults; + return result; } /** Runs the search example. */ - public List runSearch() throws IOException, ParseException { + public SimpleFacetResult runSearch() throws IOException, ParseException { index(); return search(); } @@ -127,10 +128,8 @@ public class ExpressionAggregationFacetsExample { public static void main(String[] args) throws Exception { System.out.println("Facet counting example:"); System.out.println("-----------------------"); - List results = new ExpressionAggregationFacetsExample().runSearch(); - for (FacetResult res : results) { - System.out.println(res); - } + SimpleFacetResult result = new ExpressionAggregationFacetsExample().runSearch(); + System.out.println(result); } } diff --git a/lucene/demo/src/java/org/apache/lucene/demo/facet/MultiCategoryListsFacetsExample.java b/lucene/demo/src/java/org/apache/lucene/demo/facet/MultiCategoryListsFacetsExample.java index 0e2dfc0a78a..9504d2309c4 100644 --- a/lucene/demo/src/java/org/apache/lucene/demo/facet/MultiCategoryListsFacetsExample.java +++ b/lucene/demo/src/java/org/apache/lucene/demo/facet/MultiCategoryListsFacetsExample.java @@ -1,33 +1,5 @@ package org.apache.lucene.demo.facet; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.lucene.analysis.core.WhitespaceAnalyzer; -import org.apache.lucene.document.Document; -import org.apache.lucene.facet.index.FacetFields; -import org.apache.lucene.facet.params.CategoryListParams; -import org.apache.lucene.facet.params.FacetIndexingParams; -import org.apache.lucene.facet.params.FacetSearchParams; -import org.apache.lucene.facet.params.PerDimensionIndexingParams; -import org.apache.lucene.facet.search.CountFacetRequest; -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetsCollector; -import org.apache.lucene.facet.taxonomy.FacetLabel; -import org.apache.lucene.facet.taxonomy.TaxonomyReader; -import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; -import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter; -import org.apache.lucene.index.DirectoryReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.MatchAllDocsQuery; -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.RAMDirectory; - /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -45,33 +17,52 @@ import org.apache.lucene.store.RAMDirectory; * limitations under the License. */ -/** Demonstrates indexing categories into different category lists. */ +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.lucene.analysis.core.WhitespaceAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.facet.simple.FacetField; +import org.apache.lucene.facet.simple.Facets; +import org.apache.lucene.facet.simple.FacetsConfig; +import org.apache.lucene.facet.simple.FastTaxonomyFacetCounts; +import org.apache.lucene.facet.simple.SimpleFacetResult; +import org.apache.lucene.facet.simple.SimpleFacetsCollector; +import org.apache.lucene.facet.taxonomy.FacetLabel; +import org.apache.lucene.facet.taxonomy.TaxonomyReader; +import org.apache.lucene.facet.taxonomy.TaxonomyWriter; +import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; +import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.RAMDirectory; + +/** Demonstrates indexing categories into different indexed fields. */ public class MultiCategoryListsFacetsExample { - private final FacetIndexingParams indexingParams; private final Directory indexDir = new RAMDirectory(); private final Directory taxoDir = new RAMDirectory(); /** Creates a new instance and populates the catetory list params mapping. */ public MultiCategoryListsFacetsExample() { - // index all Author facets in one category list and all Publish Date in another. - Map categoryListParams = new HashMap(); - categoryListParams.put(new FacetLabel("Author"), new CategoryListParams("author")); - categoryListParams.put(new FacetLabel("Publish Date"), new CategoryListParams("pubdate")); - indexingParams = new PerDimensionIndexingParams(categoryListParams); - } - - private void add(IndexWriter indexWriter, FacetFields facetFields, String ... categoryPaths) throws IOException { - Document doc = new Document(); - - List paths = new ArrayList(); - for (String categoryPath : categoryPaths) { - paths.add(new FacetLabel(categoryPath, '/')); - } - facetFields.addFields(doc, paths); - indexWriter.addDocument(doc); } + /** It's fine if taxoWriter is null (i.e., at search time) */ + private FacetsConfig getConfig(TaxonomyWriter taxoWriter) { + FacetsConfig config = new FacetsConfig(taxoWriter); + config.setIndexFieldName("Author", "author"); + config.setIndexFieldName("Publish Date", "pubdate"); + config.setHierarchical("Publish Date", true); + return config; + } + /** Build the example index. */ private void index() throws IOException { IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER, @@ -80,50 +71,70 @@ public class MultiCategoryListsFacetsExample { // Writes facet ords to a separate directory from the main index DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir); - // Reused across documents, to add the necessary facet fields - FacetFields facetFields = new FacetFields(taxoWriter, indexingParams); + FacetsConfig config = getConfig(taxoWriter); - add(indexWriter, facetFields, "Author/Bob", "Publish Date/2010/10/15"); - add(indexWriter, facetFields, "Author/Lisa", "Publish Date/2010/10/20"); - add(indexWriter, facetFields, "Author/Lisa", "Publish Date/2012/1/1"); - add(indexWriter, facetFields, "Author/Susan", "Publish Date/2012/1/7"); - add(indexWriter, facetFields, "Author/Frank", "Publish Date/1999/5/5"); + Document doc = new Document(); + doc.add(new FacetField("Author", "Bob")); + doc.add(new FacetField("Publish Date", "2010", "10", "15")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + doc.add(new FacetField("Author", "Lisa")); + doc.add(new FacetField("Publish Date", "2010", "10", "20")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + doc.add(new FacetField("Author", "Lisa")); + doc.add(new FacetField("Publish Date", "2012", "1", "1")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + doc.add(new FacetField("Author", "Susan")); + doc.add(new FacetField("Publish Date", "2012", "1", "7")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + doc.add(new FacetField("Author", "Frank")); + doc.add(new FacetField("Publish Date", "1999", "5", "5")); + indexWriter.addDocument(config.build(doc)); indexWriter.close(); taxoWriter.close(); } /** User runs a query and counts facets. */ - private List search() throws IOException { + private List search() throws IOException { DirectoryReader indexReader = DirectoryReader.open(indexDir); IndexSearcher searcher = new IndexSearcher(indexReader); TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir); + FacetsConfig config = getConfig(null); - // Count both "Publish Date" and "Author" dimensions - FacetSearchParams fsp = new FacetSearchParams(indexingParams, - new CountFacetRequest(new FacetLabel("Publish Date"), 10), - new CountFacetRequest(new FacetLabel("Author"), 10)); - - // Aggregatses the facet counts - FacetsCollector fc = FacetsCollector.create(fsp, searcher.getIndexReader(), taxoReader); + SimpleFacetsCollector sfc = new SimpleFacetsCollector(); // MatchAllDocsQuery is for "browsing" (counts facets // for all non-deleted docs in the index); normally // you'd use a "normal" query, and use MultiCollector to // wrap collecting the "normal" hits and also facets: - searcher.search(new MatchAllDocsQuery(), fc); + searcher.search(new MatchAllDocsQuery(), sfc); // Retrieve results - List facetResults = fc.getFacetResults(); + List results = new ArrayList(); + + // Count both "Publish Date" and "Author" dimensions + Facets author = new FastTaxonomyFacetCounts("author", taxoReader, config, sfc); + results.add(author.getTopChildren(10, "Author")); + + Facets pubDate = new FastTaxonomyFacetCounts("pubdate", taxoReader, config, sfc); + results.add(pubDate.getTopChildren(10, "Publish Date")); indexReader.close(); taxoReader.close(); - return facetResults; + return results; } /** Runs the search example. */ - public List runSearch() throws IOException { + public List runSearch() throws IOException { index(); return search(); } @@ -132,10 +143,8 @@ public class MultiCategoryListsFacetsExample { public static void main(String[] args) throws Exception { System.out.println("Facet counting over multiple category lists example:"); System.out.println("-----------------------"); - List results = new MultiCategoryListsFacetsExample().runSearch(); - for (FacetResult res : results) { - System.out.println(res); - } + List results = new MultiCategoryListsFacetsExample().runSearch(); + System.out.println("Author: " + results.get(0)); + System.out.println("Publish Date: " + results.get(1)); } - } diff --git a/lucene/demo/src/java/org/apache/lucene/demo/facet/RangeFacetsExample.java b/lucene/demo/src/java/org/apache/lucene/demo/facet/RangeFacetsExample.java index 021429f95cd..1c3c631b81b 100644 --- a/lucene/demo/src/java/org/apache/lucene/demo/facet/RangeFacetsExample.java +++ b/lucene/demo/src/java/org/apache/lucene/demo/facet/RangeFacetsExample.java @@ -26,13 +26,13 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.LongField; import org.apache.lucene.document.NumericDocValuesField; -import org.apache.lucene.facet.params.FacetIndexingParams; -import org.apache.lucene.facet.range.LongRange; -import org.apache.lucene.facet.range.RangeAccumulator; -import org.apache.lucene.facet.range.RangeFacetRequest; -import org.apache.lucene.facet.search.DrillDownQuery; -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetsCollector; +import org.apache.lucene.facet.simple.Facets; +import org.apache.lucene.facet.simple.FacetsConfig; +import org.apache.lucene.facet.simple.LongRange; +import org.apache.lucene.facet.simple.RangeFacetCounts; +import org.apache.lucene.facet.simple.SimpleDrillDownQuery; +import org.apache.lucene.facet.simple.SimpleFacetResult; +import org.apache.lucene.facet.simple.SimpleFacetsCollector; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; @@ -44,6 +44,7 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory; + /** Shows simple usage of dynamic range faceting. */ public class RangeFacetsExample implements Closeable { @@ -51,6 +52,10 @@ public class RangeFacetsExample implements Closeable { private IndexSearcher searcher; private final long nowSec = System.currentTimeMillis(); + final LongRange PAST_HOUR = new LongRange("Past hour", nowSec-3600, true, nowSec, true); + final LongRange PAST_SIX_HOURS = new LongRange("Past six hours", nowSec-6*3600, true, nowSec, true); + final LongRange PAST_DAY = new LongRange("Past day", nowSec-24*3600, true, nowSec, true); + /** Empty constructor */ public RangeFacetsExample() {} @@ -76,24 +81,27 @@ public class RangeFacetsExample implements Closeable { indexWriter.close(); } - /** User runs a query and counts facets. */ - public List search() throws IOException { + private FacetsConfig getConfig() { + return new FacetsConfig(); + } - RangeFacetRequest rangeFacetRequest = new RangeFacetRequest("timestamp", - new LongRange("Past hour", nowSec-3600, true, nowSec, true), - new LongRange("Past six hours", nowSec-6*3600, true, nowSec, true), - new LongRange("Past day", nowSec-24*3600, true, nowSec, true)); - // Aggregatses the facet counts - FacetsCollector fc = FacetsCollector.create(new RangeAccumulator(rangeFacetRequest)); + /** User runs a query and counts facets. */ + public SimpleFacetResult search() throws IOException { + + // Aggregates the facet counts + SimpleFacetsCollector sfc = new SimpleFacetsCollector(); // MatchAllDocsQuery is for "browsing" (counts facets // for all non-deleted docs in the index); normally // you'd use a "normal" query, and use MultiCollector to // wrap collecting the "normal" hits and also facets: - searcher.search(new MatchAllDocsQuery(), fc); + searcher.search(new MatchAllDocsQuery(), sfc); - // Retrieve results - return fc.getFacetResults(); + Facets facets = new RangeFacetCounts("timestamp", sfc, + PAST_HOUR, + PAST_SIX_HOURS, + PAST_DAY); + return facets.getTopChildren(10, "timestamp"); } /** User drills down on the specified range. */ @@ -101,7 +109,7 @@ public class RangeFacetsExample implements Closeable { // Passing no baseQuery means we drill down on all // documents ("browse only"): - DrillDownQuery q = new DrillDownQuery(FacetIndexingParams.DEFAULT); + SimpleDrillDownQuery q = new SimpleDrillDownQuery(getConfig()); // Use FieldCacheRangeFilter; this will use // NumericDocValues: @@ -124,15 +132,12 @@ public class RangeFacetsExample implements Closeable { System.out.println("Facet counting example:"); System.out.println("-----------------------"); - List results = example.search(); - for (FacetResult res : results) { - System.out.println(res); - } + System.out.println(example.search()); System.out.println("\n"); System.out.println("Facet drill-down example (timestamp/Past six hours):"); System.out.println("---------------------------------------------"); - TopDocs hits = example.drillDown((LongRange) ((RangeFacetRequest) results.get(0).getFacetRequest()).ranges[1]); + TopDocs hits = example.drillDown(example.PAST_SIX_HOURS); System.out.println(hits.totalHits + " totalHits"); example.close(); 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 e65feb8489e..f1a0569d723 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 @@ -1,29 +1,5 @@ package org.apache.lucene.demo.facet; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.lucene.analysis.core.WhitespaceAnalyzer; -import org.apache.lucene.document.Document; -import org.apache.lucene.facet.index.FacetFields; -import org.apache.lucene.facet.params.FacetSearchParams; -import org.apache.lucene.facet.search.CountFacetRequest; -import org.apache.lucene.facet.search.DrillDownQuery; -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetsCollector; -import org.apache.lucene.facet.taxonomy.FacetLabel; -import org.apache.lucene.facet.taxonomy.TaxonomyReader; -import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; -import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter; -import org.apache.lucene.index.DirectoryReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.MatchAllDocsQuery; -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.RAMDirectory; - /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -41,6 +17,32 @@ import org.apache.lucene.store.RAMDirectory; * limitations under the License. */ +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.lucene.analysis.core.WhitespaceAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.facet.simple.FacetField; +import org.apache.lucene.facet.simple.Facets; +import org.apache.lucene.facet.simple.FacetsConfig; +import org.apache.lucene.facet.simple.FastTaxonomyFacetCounts; +import org.apache.lucene.facet.simple.SimpleDrillDownQuery; +import org.apache.lucene.facet.simple.SimpleFacetResult; +import org.apache.lucene.facet.simple.SimpleFacetsCollector; +import org.apache.lucene.facet.taxonomy.FacetLabel; +import org.apache.lucene.facet.taxonomy.TaxonomyReader; +import org.apache.lucene.facet.taxonomy.TaxonomyWriter; +import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; +import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.RAMDirectory; + /** Shows simple usage of faceted indexing and search. */ public class SimpleFacetsExample { @@ -50,15 +52,11 @@ public class SimpleFacetsExample { /** Empty constructor */ public SimpleFacetsExample() {} - private void add(IndexWriter indexWriter, FacetFields facetFields, String ... categoryPaths) throws IOException { - Document doc = new Document(); - - List paths = new ArrayList(); - for (String categoryPath : categoryPaths) { - paths.add(new FacetLabel(categoryPath, '/')); - } - facetFields.addFields(doc, paths); - indexWriter.addDocument(doc); + /** It's fine if taxoWriter is null (i.e., at search time) */ + private FacetsConfig getConfig(TaxonomyWriter taxoWriter) { + FacetsConfig config = new FacetsConfig(taxoWriter); + config.setHierarchical("Publish Date", true); + return config; } /** Build the example index. */ @@ -69,81 +67,100 @@ public class SimpleFacetsExample { // Writes facet ords to a separate directory from the main index DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir); - // Reused across documents, to add the necessary facet fields - FacetFields facetFields = new FacetFields(taxoWriter); + FacetsConfig config = getConfig(taxoWriter); - add(indexWriter, facetFields, "Author/Bob", "Publish Date/2010/10/15"); - add(indexWriter, facetFields, "Author/Lisa", "Publish Date/2010/10/20"); - add(indexWriter, facetFields, "Author/Lisa", "Publish Date/2012/1/1"); - add(indexWriter, facetFields, "Author/Susan", "Publish Date/2012/1/7"); - add(indexWriter, facetFields, "Author/Frank", "Publish Date/1999/5/5"); + Document doc = new Document(); + doc.add(new FacetField("Author", "Bob")); + doc.add(new FacetField("Publish Date", "2010", "10", "15")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + doc.add(new FacetField("Author", "Lisa")); + doc.add(new FacetField("Publish Date", "2010", "10", "20")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + doc.add(new FacetField("Author", "Lisa")); + doc.add(new FacetField("Publish Date", "2012", "1", "1")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + doc.add(new FacetField("Author", "Susan")); + doc.add(new FacetField("Publish Date", "2012", "1", "7")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + doc.add(new FacetField("Author", "Frank")); + doc.add(new FacetField("Publish Date", "1999", "5", "5")); + indexWriter.addDocument(config.build(doc)); indexWriter.close(); taxoWriter.close(); } /** User runs a query and counts facets. */ - private List search() throws IOException { + private List search() throws IOException { DirectoryReader indexReader = DirectoryReader.open(indexDir); IndexSearcher searcher = new IndexSearcher(indexReader); TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir); + FacetsConfig config = getConfig(null); - // Count both "Publish Date" and "Author" dimensions - FacetSearchParams fsp = new FacetSearchParams( - new CountFacetRequest(new FacetLabel("Publish Date"), 10), - new CountFacetRequest(new FacetLabel("Author"), 10)); - - // Aggregates the facet counts - FacetsCollector fc = FacetsCollector.create(fsp, searcher.getIndexReader(), taxoReader); + SimpleFacetsCollector sfc = new SimpleFacetsCollector(); // MatchAllDocsQuery is for "browsing" (counts facets // for all non-deleted docs in the index); normally // you'd use a "normal" query, and use MultiCollector to // wrap collecting the "normal" hits and also facets: - searcher.search(new MatchAllDocsQuery(), fc); + searcher.search(new MatchAllDocsQuery(), sfc); // Retrieve results - List facetResults = fc.getFacetResults(); + List results = new ArrayList(); + + // Count both "Publish Date" and "Author" dimensions + Facets facets = new FastTaxonomyFacetCounts(taxoReader, config, sfc); + results.add(facets.getTopChildren(10, "Author")); + results.add(facets.getTopChildren(10, "Publish Date")); indexReader.close(); taxoReader.close(); - return facetResults; + return results; } /** User drills down on 'Publish Date/2010'. */ - private List drillDown() throws IOException { + private SimpleFacetResult drillDown() throws IOException { DirectoryReader indexReader = DirectoryReader.open(indexDir); IndexSearcher searcher = new IndexSearcher(indexReader); TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir); - - // Now user drills down on Publish Date/2010: - FacetSearchParams fsp = new FacetSearchParams(new CountFacetRequest(new FacetLabel("Author"), 10)); + FacetsConfig config = getConfig(null); // Passing no baseQuery means we drill down on all // documents ("browse only"): - DrillDownQuery q = new DrillDownQuery(fsp.indexingParams); - q.add(new FacetLabel("Publish Date/2010", '/')); - FacetsCollector fc = FacetsCollector.create(fsp, searcher.getIndexReader(), taxoReader); - searcher.search(q, fc); + SimpleDrillDownQuery q = new SimpleDrillDownQuery(config); + + // Now user drills down on Publish Date/2010: + q.add("Publish Date", "2010"); + SimpleFacetsCollector sfc = new SimpleFacetsCollector(); + searcher.search(q, sfc); // Retrieve results - List facetResults = fc.getFacetResults(); - + Facets facets = new FastTaxonomyFacetCounts(taxoReader, config, sfc); + SimpleFacetResult result = facets.getTopChildren(10, "Author"); + indexReader.close(); taxoReader.close(); - return facetResults; + return result; } /** Runs the search example. */ - public List runSearch() throws IOException { + public List runSearch() throws IOException { index(); return search(); } /** Runs the drill-down example. */ - public List runDrillDown() throws IOException { + public SimpleFacetResult runDrillDown() throws IOException { index(); return drillDown(); } @@ -152,18 +169,15 @@ public class SimpleFacetsExample { public static void main(String[] args) throws Exception { System.out.println("Facet counting example:"); System.out.println("-----------------------"); - List results = new SimpleFacetsExample().runSearch(); - for (FacetResult res : results) { - System.out.println(res); - } + SimpleFacetsExample example = new SimpleFacetsExample(); + List results = example.runSearch(); + 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("---------------------------------------------"); - results = new SimpleFacetsExample().runDrillDown(); - for (FacetResult res : results) { - System.out.println(res); - } + System.out.println("Author: " + example.runDrillDown()); } } diff --git a/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleSortedSetFacetsExample.java b/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleSortedSetFacetsExample.java index 52dec490351..b42117a69f2 100644 --- a/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleSortedSetFacetsExample.java +++ b/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleSortedSetFacetsExample.java @@ -23,14 +23,14 @@ import java.util.List; import org.apache.lucene.analysis.core.WhitespaceAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.facet.params.FacetSearchParams; -import org.apache.lucene.facet.search.CountFacetRequest; -import org.apache.lucene.facet.search.DrillDownQuery; -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetsCollector; -import org.apache.lucene.facet.sortedset.SortedSetDocValuesAccumulator; -import org.apache.lucene.facet.sortedset.SortedSetDocValuesFacetFields; -import org.apache.lucene.facet.sortedset.SortedSetDocValuesReaderState; +import org.apache.lucene.facet.simple.Facets; +import org.apache.lucene.facet.simple.FacetsConfig; +import org.apache.lucene.facet.simple.SimpleDrillDownQuery; +import org.apache.lucene.facet.simple.SimpleFacetResult; +import org.apache.lucene.facet.simple.SimpleFacetsCollector; +import org.apache.lucene.facet.simple.SortedSetDocValuesFacetCounts; +import org.apache.lucene.facet.simple.SortedSetDocValuesFacetField; +import org.apache.lucene.facet.simple.SortedSetDocValuesReaderState; import org.apache.lucene.facet.taxonomy.FacetLabel; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexWriter; @@ -51,91 +51,99 @@ public class SimpleSortedSetFacetsExample { /** Empty constructor */ public SimpleSortedSetFacetsExample() {} - private void add(IndexWriter indexWriter, SortedSetDocValuesFacetFields facetFields, String ... categoryPaths) throws IOException { - Document doc = new Document(); - - List paths = new ArrayList(); - for (String categoryPath : categoryPaths) { - paths.add(new FacetLabel(categoryPath, '/')); - } - facetFields.addFields(doc, paths); - indexWriter.addDocument(doc); + private FacetsConfig getConfig() { + return new FacetsConfig(); } /** Build the example index. */ private void index() throws IOException { IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER, new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER))); + FacetsConfig config = getConfig(); + Document doc = new Document(); + doc.add(new SortedSetDocValuesFacetField("Author", "Bob")); + doc.add(new SortedSetDocValuesFacetField("Publish Year", "2010")); + indexWriter.addDocument(config.build(doc)); - // Reused across documents, to add the necessary facet fields - SortedSetDocValuesFacetFields facetFields = new SortedSetDocValuesFacetFields(); + doc = new Document(); + doc.add(new SortedSetDocValuesFacetField("Author", "Lisa")); + doc.add(new SortedSetDocValuesFacetField("Publish Year", "2010")); + indexWriter.addDocument(config.build(doc)); - add(indexWriter, facetFields, "Author/Bob", "Publish Year/2010"); - add(indexWriter, facetFields, "Author/Lisa", "Publish Year/2010"); - add(indexWriter, facetFields, "Author/Lisa", "Publish Year/2012"); - add(indexWriter, facetFields, "Author/Susan", "Publish Year/2012"); - add(indexWriter, facetFields, "Author/Frank", "Publish Year/1999"); + doc = new Document(); + doc.add(new SortedSetDocValuesFacetField("Author", "Lisa")); + doc.add(new SortedSetDocValuesFacetField("Publish Year", "2012")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + doc.add(new SortedSetDocValuesFacetField("Author", "Susan")); + doc.add(new SortedSetDocValuesFacetField("Publish Year", "2012")); + indexWriter.addDocument(config.build(doc)); + + doc = new Document(); + doc.add(new SortedSetDocValuesFacetField("Author", "Frank")); + doc.add(new SortedSetDocValuesFacetField("Publish Year", "1999")); + indexWriter.addDocument(config.build(doc)); indexWriter.close(); } /** User runs a query and counts facets. */ - private List search() throws IOException { + private List search() throws IOException { DirectoryReader indexReader = DirectoryReader.open(indexDir); IndexSearcher searcher = new IndexSearcher(indexReader); SortedSetDocValuesReaderState state = new SortedSetDocValuesReaderState(indexReader); - - // Count both "Publish Year" and "Author" dimensions - FacetSearchParams fsp = new FacetSearchParams( - new CountFacetRequest(new FacetLabel("Publish Year"), 10), - new CountFacetRequest(new FacetLabel("Author"), 10)); + FacetsConfig config = getConfig(); // Aggregatses the facet counts - FacetsCollector fc = FacetsCollector.create(new SortedSetDocValuesAccumulator(state, fsp)); + SimpleFacetsCollector sfc = new SimpleFacetsCollector(); // MatchAllDocsQuery is for "browsing" (counts facets // for all non-deleted docs in the index); normally // you'd use a "normal" query, and use MultiCollector to // wrap collecting the "normal" hits and also facets: - searcher.search(new MatchAllDocsQuery(), fc); + searcher.search(new MatchAllDocsQuery(), sfc); // Retrieve results - List facetResults = fc.getFacetResults(); - + Facets facets = new SortedSetDocValuesFacetCounts(state, sfc); + + List results = new ArrayList(); + results.add(facets.getTopChildren(10, "Author")); + results.add(facets.getTopChildren(10, "Publish Year")); indexReader.close(); - return facetResults; + return results; } /** User drills down on 'Publish Year/2010'. */ - private List drillDown() throws IOException { + private SimpleFacetResult drillDown() throws IOException { DirectoryReader indexReader = DirectoryReader.open(indexDir); IndexSearcher searcher = new IndexSearcher(indexReader); SortedSetDocValuesReaderState state = new SortedSetDocValuesReaderState(indexReader); + FacetsConfig config = getConfig(); // Now user drills down on Publish Year/2010: - FacetSearchParams fsp = new FacetSearchParams(new CountFacetRequest(new FacetLabel("Author"), 10)); - DrillDownQuery q = new DrillDownQuery(fsp.indexingParams, new MatchAllDocsQuery()); - q.add(new FacetLabel("Publish Year/2010", '/')); - FacetsCollector fc = FacetsCollector.create(new SortedSetDocValuesAccumulator(state, fsp)); - searcher.search(q, fc); + SimpleDrillDownQuery q = new SimpleDrillDownQuery(config); + q.add("Publish Year", "2010"); + SimpleFacetsCollector sfc = new SimpleFacetsCollector(); + searcher.search(q, sfc); // Retrieve results - List facetResults = fc.getFacetResults(); - + Facets facets = new SortedSetDocValuesFacetCounts(state, sfc); + SimpleFacetResult result = facets.getTopChildren(10, "Author"); indexReader.close(); - return facetResults; + return result; } /** Runs the search example. */ - public List runSearch() throws IOException { + public List runSearch() throws IOException { index(); return search(); } /** Runs the drill-down example. */ - public List runDrillDown() throws IOException { + public SimpleFacetResult runDrillDown() throws IOException { index(); return drillDown(); } @@ -144,18 +152,14 @@ public class SimpleSortedSetFacetsExample { public static void main(String[] args) throws Exception { System.out.println("Facet counting example:"); System.out.println("-----------------------"); - List results = new SimpleSortedSetFacetsExample().runSearch(); - for (FacetResult res : results) { - System.out.println(res); - } + SimpleSortedSetFacetsExample example = new SimpleSortedSetFacetsExample(); + List results = example.runSearch(); + System.out.println("Author: " + results.get(0)); + System.out.println("Publish Year: " + results.get(0)); System.out.println("\n"); System.out.println("Facet drill-down example (Publish Year/2010):"); System.out.println("---------------------------------------------"); - results = new SimpleSortedSetFacetsExample().runDrillDown(); - for (FacetResult res : results) { - System.out.println(res); - } + System.out.println("Author: " + example.runDrillDown()); } - } diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java index d38739626ce..1455a36b4b4 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java @@ -1,12 +1,5 @@ package org.apache.lucene.demo.facet; -import java.util.List; - -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetResultNode; -import org.apache.lucene.util.LuceneTestCase; -import org.junit.Test; - /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -24,32 +17,19 @@ import org.junit.Test; * limitations under the License. */ +import java.util.List; + +import org.apache.lucene.facet.simple.SimpleFacetResult; +import org.apache.lucene.util.LuceneTestCase; +import org.junit.Test; + public class TestAssociationsFacetsExample extends LuceneTestCase { - private static final double[] EXPECTED_INT_SUM_RESULTS = { 4, 2}; - private static final double[] EXPECTED_FLOAT_SUM_RESULTS = { 1.62, 0.34}; - @Test public void testExamples() throws Exception { - List res = new AssociationsFacetsExample().runSumAssociations(); - + List res = new AssociationsFacetsExample().runSumAssociations(); assertEquals("Wrong number of results", 2, res.size()); - - for (FacetResult fres : res) { - assertEquals("Wrong number of facets", 2, fres.getNumValidDescendants()); - } - - Iterable it = res.get(0).getFacetResultNode().subResults; - int i = 0; - for (FacetResultNode fResNode : it) { - assertEquals("Wrong result for facet " + fResNode.label, EXPECTED_INT_SUM_RESULTS[i++], fResNode.value, 1E-5); - } - - it = res.get(1).getFacetResultNode().subResults; - i = 0; - for (FacetResultNode fResNode : it) { - assertEquals("Wrong result for facet " + fResNode.label, EXPECTED_FLOAT_SUM_RESULTS[i++], fResNode.value, 1E-5); - } - } - + assertEquals("value=6 childCount=2\n lucene (4)\n solr (2)\n", res.get(0).toString()); + assertEquals("value=1.96 childCount=2\n computing (1.62)\n software (0.34)\n", res.get(1).toString()); + } } diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java index ebac9d3c0ab..2b0a59ac7d5 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java @@ -1,13 +1,5 @@ package org.apache.lucene.demo.facet; -import java.util.List; -import java.util.Locale; - -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetResultNode; -import org.apache.lucene.util.LuceneTestCase; -import org.junit.Test; - /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -25,25 +17,18 @@ import org.junit.Test; * limitations under the License. */ -public class TestExpressionAggregationFacetsExample extends LuceneTestCase { +import java.util.List; +import java.util.Locale; - private static String toSimpleString(FacetResult fr) { - StringBuilder sb = new StringBuilder(); - toSimpleString(fr.getFacetRequest().categoryPath.length, 0, sb, fr.getFacetResultNode(), ""); - return sb.toString(); - } - - private static void toSimpleString(int startLength, int depth, StringBuilder sb, FacetResultNode node, String indent) { - sb.append(String.format(Locale.ROOT, "%s%s (%.3f)\n", indent, node.label.components[startLength + depth - 1], node.value)); - for (FacetResultNode childNode : node.subResults) { - toSimpleString(startLength, depth + 1, sb, childNode, indent + " "); - } - } +import org.apache.lucene.facet.simple.SimpleFacetResult; +import org.apache.lucene.util.LuceneTestCase; +import org.junit.Test; + +public class TestExpressionAggregationFacetsExample extends LuceneTestCase { @Test public void testSimple() throws Exception { - List facetResults = new ExpressionAggregationFacetsExample().runSearch(); - assertEquals("A (0.000)\n B (2.236)\n C (1.732)\n", toSimpleString(facetResults.get(0))); + SimpleFacetResult result = new ExpressionAggregationFacetsExample().runSearch(); + assertEquals("value=3.9681187 childCount=2\n B (2.236068)\n C (1.7320508)\n", result.toString()); } - } diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java index 76baf0614f6..af2b89fa5af 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java @@ -1,14 +1,5 @@ package org.apache.lucene.demo.facet; -import java.util.List; - -import org.apache.lucene.facet.collections.ObjectToIntMap; -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetResultNode; -import org.apache.lucene.facet.taxonomy.FacetLabel; -import org.apache.lucene.util.LuceneTestCase; -import org.junit.Test; - /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -26,33 +17,19 @@ import org.junit.Test; * limitations under the License. */ -public class TestMultiCategoryListsFacetsExample extends LuceneTestCase { +import java.util.List; - private static final ObjectToIntMap expectedCounts = new ObjectToIntMap(); - static { - expectedCounts.put(new FacetLabel("Publish Date", "2012"), 2); - expectedCounts.put(new FacetLabel("Publish Date", "2010"), 2); - expectedCounts.put(new FacetLabel("Publish Date", "1999"), 1); - expectedCounts.put(new FacetLabel("Author", "Lisa"), 2); - expectedCounts.put(new FacetLabel("Author", "Frank"), 1); - expectedCounts.put(new FacetLabel("Author", "Susan"), 1); - expectedCounts.put(new FacetLabel("Author", "Bob"), 1); - } - - private void assertExpectedCounts(List facetResults, ObjectToIntMap expCounts) { - for (FacetResult res : facetResults) { - FacetResultNode root = res.getFacetResultNode(); - for (FacetResultNode node : root.subResults) { - assertEquals("incorrect count for " + node.label, expCounts.get(node.label), (int) node.value); - } - } - } +import org.apache.lucene.facet.simple.SimpleFacetResult; +import org.apache.lucene.util.LuceneTestCase; +import org.junit.Test; + +public class TestMultiCategoryListsFacetsExample extends LuceneTestCase { @Test public void testExample() throws Exception { - List facetResults = new MultiCategoryListsFacetsExample().runSearch(); - assertEquals(2, facetResults.size()); - assertExpectedCounts(facetResults, expectedCounts); + List results = new MultiCategoryListsFacetsExample().runSearch(); + assertEquals(2, results.size()); + assertEquals("value=5 childCount=4\n Lisa (2)\n Bob (1)\n Susan (1)\n Frank (1)\n", results.get(0).toString()); + assertEquals("value=5 childCount=3\n 2010 (2)\n 2012 (2)\n 1999 (1)\n", results.get(1).toString()); } - } diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java index aeaab50e57d..5865f8d631a 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java @@ -19,12 +19,7 @@ package org.apache.lucene.demo.facet; import java.util.List; -import org.apache.lucene.facet.collections.ObjectToIntMap; -import org.apache.lucene.facet.range.LongRange; -import org.apache.lucene.facet.range.RangeFacetRequest; -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetResultNode; -import org.apache.lucene.facet.taxonomy.FacetLabel; +import org.apache.lucene.facet.simple.SimpleFacetResult; import org.apache.lucene.search.TopDocs; import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; import org.apache.lucene.util.LuceneTestCase; @@ -33,27 +28,12 @@ import org.junit.Test; @SuppressCodecs("Lucene3x") public class TestRangeFacetsExample extends LuceneTestCase { - private static final ObjectToIntMap expectedCounts = new ObjectToIntMap(); - static { - expectedCounts.put(new FacetLabel("timestamp", "Past hour"), 4); - expectedCounts.put(new FacetLabel("timestamp", "Past six hours"), 22); - expectedCounts.put(new FacetLabel("timestamp", "Past day"), 87); - } - - private void assertExpectedCounts(FacetResult res, ObjectToIntMap expCounts) { - FacetResultNode root = res.getFacetResultNode(); - for (FacetResultNode node : root.subResults) { - assertEquals("incorrect count for " + node.label, expCounts.get(node.label), (int) node.value); - } - } - @Test public void testSimple() throws Exception { RangeFacetsExample example = new RangeFacetsExample(); example.index(); - List facetResults = example.search(); - assertEquals(1, facetResults.size()); - assertExpectedCounts(facetResults.get(0), expectedCounts); + SimpleFacetResult result = example.search(); + assertEquals("value=100 childCount=3\n Past hour (4)\n Past six hours (22)\n Past day (87)\n", result.toString()); example.close(); } @@ -62,8 +42,7 @@ public class TestRangeFacetsExample extends LuceneTestCase { public void testDrillDown() throws Exception { RangeFacetsExample example = new RangeFacetsExample(); example.index(); - List facetResults = example.search(); - TopDocs hits = example.drillDown((LongRange) ((RangeFacetRequest) facetResults.get(0).getFacetRequest()).ranges[1]); + TopDocs hits = example.drillDown(example.PAST_SIX_HOURS); assertEquals(22, hits.totalHits); example.close(); } 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 ba9952b2740..4e66121ce12 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 @@ -1,14 +1,5 @@ package org.apache.lucene.demo.facet; -import java.util.List; - -import org.apache.lucene.facet.collections.ObjectToIntMap; -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetResultNode; -import org.apache.lucene.facet.taxonomy.FacetLabel; -import org.apache.lucene.util.LuceneTestCase; -import org.junit.Test; - /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -26,46 +17,26 @@ import org.junit.Test; * limitations under the License. */ +import java.util.List; + +import org.apache.lucene.facet.simple.SimpleFacetResult; +import org.apache.lucene.facet.taxonomy.FacetLabel; +import org.apache.lucene.util.LuceneTestCase; +import org.junit.Test; + public class TestSimpleFacetsExample extends LuceneTestCase { - private static final ObjectToIntMap expectedCounts = new ObjectToIntMap(); - static { - expectedCounts.put(new FacetLabel("Publish Date", "2012"), 2); - expectedCounts.put(new FacetLabel("Publish Date", "2010"), 2); - expectedCounts.put(new FacetLabel("Publish Date", "1999"), 1); - expectedCounts.put(new FacetLabel("Author", "Lisa"), 2); - expectedCounts.put(new FacetLabel("Author", "Frank"), 1); - expectedCounts.put(new FacetLabel("Author", "Susan"), 1); - expectedCounts.put(new FacetLabel("Author", "Bob"), 1); - } - - private static final ObjectToIntMap expectedCountsDrillDown = new ObjectToIntMap(); - static { - expectedCountsDrillDown.put(new FacetLabel("Author", "Lisa"), 1); - expectedCountsDrillDown.put(new FacetLabel("Author", "Bob"), 1); - } - - private void assertExpectedCounts(List facetResults, ObjectToIntMap expCounts) { - for (FacetResult res : facetResults) { - FacetResultNode root = res.getFacetResultNode(); - for (FacetResultNode node : root.subResults) { - assertEquals("incorrect count for " + node.label, expCounts.get(node.label), (int) node.value); - } - } - } - @Test public void testSimple() throws Exception { - List facetResults = new SimpleFacetsExample().runSearch(); - assertEquals(2, facetResults.size()); - assertExpectedCounts(facetResults, expectedCounts); + List results = new SimpleFacetsExample().runSearch(); + assertEquals(2, results.size()); + assertEquals("value=5 childCount=4\n Lisa (2)\n Bob (1)\n Susan (1)\n Frank (1)\n", results.get(0).toString()); + assertEquals("value=5 childCount=3\n 2010 (2)\n 2012 (2)\n 1999 (1)\n", results.get(1).toString()); } @Test public void testDrillDown() throws Exception { - List facetResults = new SimpleFacetsExample().runDrillDown(); - assertEquals(1, facetResults.size()); - assertExpectedCounts(facetResults, expectedCountsDrillDown); + SimpleFacetResult result = new SimpleFacetsExample().runDrillDown(); + assertEquals("value=2 childCount=2\n Bob (1)\n Lisa (1)\n", result.toString()); } - } diff --git a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java index 7299fd726de..9e3e46cfdd9 100644 --- a/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java +++ b/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java @@ -1,15 +1,5 @@ package org.apache.lucene.demo.facet; -import java.util.List; - -import org.apache.lucene.facet.collections.ObjectToIntMap; -import org.apache.lucene.facet.search.FacetResult; -import org.apache.lucene.facet.search.FacetResultNode; -import org.apache.lucene.facet.taxonomy.FacetLabel; -import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; -import org.apache.lucene.util.LuceneTestCase; -import org.junit.Test; - /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -27,48 +17,30 @@ import org.junit.Test; * limitations under the License. */ +import java.util.List; + +import org.apache.lucene.facet.simple.SimpleFacetResult; +import org.apache.lucene.facet.taxonomy.FacetLabel; +import org.apache.lucene.util.LuceneTestCase.SuppressCodecs; +import org.apache.lucene.util.LuceneTestCase; +import org.junit.Test; + + // We require sorted set DVs: @SuppressCodecs({"Lucene40", "Lucene41"}) public class TestSimpleSortedSetFacetsExample extends LuceneTestCase { - private static final ObjectToIntMap expectedCounts = new ObjectToIntMap(); - static { - expectedCounts.put(new FacetLabel("Publish Year", "2012"), 2); - expectedCounts.put(new FacetLabel("Publish Year", "2010"), 2); - expectedCounts.put(new FacetLabel("Publish Year", "1999"), 1); - expectedCounts.put(new FacetLabel("Author", "Lisa"), 2); - expectedCounts.put(new FacetLabel("Author", "Frank"), 1); - expectedCounts.put(new FacetLabel("Author", "Susan"), 1); - expectedCounts.put(new FacetLabel("Author", "Bob"), 1); - } - - private static final ObjectToIntMap expectedCountsDrillDown = new ObjectToIntMap(); - static { - expectedCountsDrillDown.put(new FacetLabel("Author", "Lisa"), 1); - expectedCountsDrillDown.put(new FacetLabel("Author", "Bob"), 1); - } - - private void assertExpectedCounts(List facetResults, ObjectToIntMap expCounts) { - for (FacetResult res : facetResults) { - FacetResultNode root = res.getFacetResultNode(); - for (FacetResultNode node : root.subResults) { - assertEquals("incorrect count for " + node.label, expCounts.get(node.label), (int) node.value); - } - } - } - @Test public void testSimple() throws Exception { - List facetResults = new SimpleSortedSetFacetsExample().runSearch(); - assertEquals(2, facetResults.size()); - assertExpectedCounts(facetResults, expectedCounts); + List results = new SimpleSortedSetFacetsExample().runSearch(); + assertEquals(2, results.size()); + assertEquals("value=5 childCount=4\n Lisa (2)\n Bob (1)\n Frank (1)\n Susan (1)\n", results.get(0).toString()); + assertEquals("value=5 childCount=3\n 2010 (2)\n 2012 (2)\n 1999 (1)\n", results.get(1).toString()); } @Test public void testDrillDown() throws Exception { - List facetResults = new SimpleSortedSetFacetsExample().runDrillDown(); - assertEquals(1, facetResults.size()); - assertExpectedCounts(facetResults, expectedCountsDrillDown); + SimpleFacetResult result = new SimpleSortedSetFacetsExample().runDrillDown(); + assertEquals("value=2 childCount=2\n Bob (1)\n Lisa (1)\n", result.toString()); } - } diff --git a/lucene/facet/src/java/org/apache/lucene/facet/simple/TaxonomyFacetSumFloatAssociations.java b/lucene/facet/src/java/org/apache/lucene/facet/simple/TaxonomyFacetSumFloatAssociations.java index 28d0db87932..337efcb631a 100644 --- a/lucene/facet/src/java/org/apache/lucene/facet/simple/TaxonomyFacetSumFloatAssociations.java +++ b/lucene/facet/src/java/org/apache/lucene/facet/simple/TaxonomyFacetSumFloatAssociations.java @@ -141,7 +141,7 @@ public class TaxonomyFacetSumFloatAssociations extends TaxonomyFacets { for(int i=labelValues.length-1;i>=0;i--) { TopOrdAndFloatQueue.OrdAndValue ordAndValue = q.pop(); FacetLabel child = taxoReader.getPath(ordAndValue.ord); - labelValues[i] = new LabelAndValue(child.components[path.length], ordAndValue.value); + labelValues[i] = new LabelAndValue(child.components[cp.length], ordAndValue.value); } return new SimpleFacetResult(sumValue, labelValues, childCount); diff --git a/lucene/facet/src/java/org/apache/lucene/facet/simple/TaxonomyFacetSumIntAssociations.java b/lucene/facet/src/java/org/apache/lucene/facet/simple/TaxonomyFacetSumIntAssociations.java index 0e5552c78ab..f6a833e1d6c 100644 --- a/lucene/facet/src/java/org/apache/lucene/facet/simple/TaxonomyFacetSumIntAssociations.java +++ b/lucene/facet/src/java/org/apache/lucene/facet/simple/TaxonomyFacetSumIntAssociations.java @@ -142,7 +142,7 @@ public class TaxonomyFacetSumIntAssociations extends TaxonomyFacets { for(int i=labelValues.length-1;i>=0;i--) { TopOrdAndIntQueue.OrdAndValue ordAndValue = q.pop(); FacetLabel child = taxoReader.getPath(ordAndValue.ord); - labelValues[i] = new LabelAndValue(child.components[path.length], ordAndValue.value); + labelValues[i] = new LabelAndValue(child.components[cp.length], ordAndValue.value); } return new SimpleFacetResult(sumValue, labelValues, childCount); diff --git a/lucene/facet/src/test/org/apache/lucene/facet/simple/TestTaxonomyFacetAssociations.java b/lucene/facet/src/test/org/apache/lucene/facet/simple/TestTaxonomyFacetAssociations.java index 2a0fdd511f8..186060d9db6 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/simple/TestTaxonomyFacetAssociations.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/simple/TestTaxonomyFacetAssociations.java @@ -107,7 +107,7 @@ public class TestTaxonomyFacetAssociations extends FacetTestCase { searcher.search(new MatchAllDocsQuery(), fc); Facets facets = new TaxonomyFacetSumIntAssociations("$facets.int", taxoReader, config, fc); - + assertEquals("value=350 childCount=2\n a (200)\n b (150)\n", facets.getTopChildren(10, "int").toString()); assertEquals("Wrong count for category 'a'!", 200, facets.getSpecificValue("int", "a").intValue()); assertEquals("Wrong count for category 'b'!", 150, facets.getSpecificValue("int", "b").intValue()); } @@ -119,6 +119,7 @@ public class TestTaxonomyFacetAssociations extends FacetTestCase { searcher.search(new MatchAllDocsQuery(), fc); Facets facets = new TaxonomyFacetSumFloatAssociations("$facets.float", taxoReader, config, fc); + assertEquals("value=59.999996 childCount=2\n a (50.0)\n b (9.999995)\n", facets.getTopChildren(10, "float").toString()); assertEquals("Wrong count for category 'a'!", 50f, facets.getSpecificValue("float", "a").floatValue(), 0.00001); assertEquals("Wrong count for category 'b'!", 10f, facets.getSpecificValue("float", "b").floatValue(), 0.00001); }