You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sh...@apache.org on 2013/02/10 13:55:40 UTC
svn commit: r1444538 - in /lucene/dev/trunk/lucene/demo/src:
java/org/apache/lucene/demo/facet/
java/org/apache/lucene/demo/facet/adaptive/
java/org/apache/lucene/demo/facet/association/
java/org/apache/lucene/demo/facet/multiCL/ java/org/apache/lucene...
Author: shaie
Date: Sun Feb 10 12:55:40 2013
New Revision: 1444538
URL: http://svn.apache.org/r1444538
Log:
LUCENE-4762: improve facet examples
Added:
lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/AssociationsFacetsExample.java (with props)
lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/FacetExamples.java
- copied, changed from r1444520, lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/ExampleUtils.java
lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/MultiCategoryListsFacetsExample.java (with props)
lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleFacetsExample.java (with props)
lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java (with props)
lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java (with props)
lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java (with props)
Removed:
lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/ExampleResult.java
lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/ExampleUtils.java
lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/adaptive/
lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/association/
lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/multiCL/
lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/simple/
lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAdaptiveExample.java
lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationExample.java
lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCLExample.java
lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleExample.java
Added: lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/AssociationsFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/AssociationsFacetsExample.java?rev=1444538&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/AssociationsFacetsExample.java (added)
+++ lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/AssociationsFacetsExample.java Sun Feb 10 12:55:40 2013
@@ -0,0 +1,209 @@
+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.AssociationFloatSumFacetRequest;
+import org.apache.lucene.facet.associations.AssociationIntSumFacetRequest;
+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.index.FacetFields;
+import org.apache.lucene.facet.params.FacetSearchParams;
+import org.apache.lucene.facet.search.FacetResult;
+import org.apache.lucene.facet.search.FacetsAccumulator;
+import org.apache.lucene.facet.search.FacetsCollector;
+import org.apache.lucene.facet.search.StandardFacetsAccumulator;
+import org.apache.lucene.facet.taxonomy.CategoryPath;
+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
+ * 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.
+ */
+
+/** Shows example usage of category associations. */
+public class AssociationsFacetsExample {
+
+ /**
+ * Categories per document, {@link #ASSOCIATIONS} hold the association value
+ * for each category.
+ */
+ public static CategoryPath[][] CATEGORIES = {
+ // Doc #1
+ { new CategoryPath("tags", "lucene") ,
+ new CategoryPath("genre", "computing")
+ },
+
+ // Doc #2
+ { new CategoryPath("tags", "lucene"),
+ new CategoryPath("tags", "solr"),
+ new CategoryPath("genre", "computing"),
+ new CategoryPath("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();
+
+ /** Empty constructor */
+ public 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)));
+
+ // Writes facet ords to a separate directory from the main index
+ DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir, IndexWriterConfig.OpenMode.CREATE);
+
+ // 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);
+ }
+
+ indexWriter.close();
+ taxoWriter.close();
+ }
+
+ /** User runs a query and aggregates facets by summing their int associations. */
+ private List<FacetResult> sumIntAssociations() throws IOException {
+ DirectoryReader indexReader = DirectoryReader.open(indexDir);
+ IndexSearcher searcher = new IndexSearcher(indexReader);
+ TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
+
+ // sum the 'tags' dimension
+ FacetSearchParams fsp = new FacetSearchParams(new AssociationIntSumFacetRequest(new CategoryPath("tags"), 10));
+
+ FacetsAccumulator fa = new StandardFacetsAccumulator(fsp, indexReader, taxoReader);
+ FacetsCollector fc = FacetsCollector.create(fa);
+
+ // 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);
+
+ // Retrieve results
+ List<FacetResult> facetResults = fc.getFacetResults();
+
+ indexReader.close();
+ taxoReader.close();
+
+ return facetResults;
+ }
+
+ /** User runs a query and aggregates facets by summing their float associations. */
+ private List<FacetResult> sumFloatAssociations() throws IOException {
+ DirectoryReader indexReader = DirectoryReader.open(indexDir);
+ IndexSearcher searcher = new IndexSearcher(indexReader);
+ TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
+
+ // sum the 'tags' dimension
+ FacetSearchParams fsp = new FacetSearchParams(new AssociationFloatSumFacetRequest(new CategoryPath("genre"), 10));
+
+ FacetsAccumulator fa = new StandardFacetsAccumulator(fsp, indexReader, taxoReader);
+ FacetsCollector fc = FacetsCollector.create(fa);
+
+ // 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);
+
+ // Retrieve results
+ List<FacetResult> facetResults = fc.getFacetResults();
+
+ indexReader.close();
+ taxoReader.close();
+
+ return facetResults;
+ }
+
+ /** Runs summing int association example. */
+ public List<FacetResult> runSumIntAssociations() throws IOException {
+ index();
+ return sumIntAssociations();
+ }
+
+ /** Runs summing float association example. */
+ public List<FacetResult> runSumFloatAssociations() throws IOException {
+ index();
+ return sumFloatAssociations();
+ }
+
+ /** Runs the sum int/float associations examples and prints the results. */
+ public static void main(String[] args) throws Exception {
+ System.out.println("Sum int-associations example:");
+ System.out.println("-----------------------------");
+ List<FacetResult> results = new AssociationsFacetsExample().runSumIntAssociations();
+ for (FacetResult res : results) {
+ System.out.println(res);
+ }
+
+ System.out.println("\n");
+ System.out.println("Sum float-associations example:");
+ System.out.println("-------------------------------");
+ results = new AssociationsFacetsExample().runSumFloatAssociations();
+ for (FacetResult res : results) {
+ System.out.println(res);
+ }
+ }
+
+}
Copied: lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/FacetExamples.java (from r1444520, lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/ExampleUtils.java)
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/FacetExamples.java?p2=lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/FacetExamples.java&p1=lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/ExampleUtils.java&r1=1444520&r2=1444538&rev=1444538&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/ExampleUtils.java (original)
+++ lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/FacetExamples.java Sun Feb 10 12:55:40 2013
@@ -20,32 +20,13 @@ import org.apache.lucene.util.Version;
*/
/**
- * Simple utility functions for the faceting examples
+ * Hold various constants used by facet examples.
+ *
* @lucene.experimental
*/
-public class ExampleUtils {
+public interface FacetExamples {
- /** No instance */
- private ExampleUtils() {}
-
- /**
- * True if the system property <code>tests.verbose</code> has been set.
- * If true, it causes {@link #log(Object)} to print messages to the console.
- */
- public static final boolean VERBOSE = Boolean.getBoolean("tests.verbose");
-
/** The Lucene {@link Version} used by the example code. */
- public static final Version EXAMPLE_VER = Version.LUCENE_40;
-
- /**
- * Logs the String representation of <code>msg</code> to the console,
- * if {@link #VERBOSE} is true. Otherwise, does nothing.
- * @see #VERBOSE
- */
- public static void log(Object msg) {
- if (VERBOSE) {
- System.out.println(msg.toString());
- }
- }
+ public static final Version EXAMPLES_VER = Version.LUCENE_50;
}
Added: lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/MultiCategoryListsFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/MultiCategoryListsFacetsExample.java?rev=1444538&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/MultiCategoryListsFacetsExample.java (added)
+++ lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/MultiCategoryListsFacetsExample.java Sun Feb 10 12:55:40 2013
@@ -0,0 +1,141 @@
+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.CategoryPath;
+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
+ * 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.
+ */
+
+/** Demonstrates indexing categories into different category lists. */
+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<CategoryPath,CategoryListParams> categoryListParams = new HashMap<CategoryPath,CategoryListParams>();
+ categoryListParams.put(new CategoryPath("Author"), new CategoryListParams("author"));
+ categoryListParams.put(new CategoryPath("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<CategoryPath> paths = new ArrayList<CategoryPath>();
+ for (String categoryPath : categoryPaths) {
+ paths.add(new CategoryPath(categoryPath, '/'));
+ }
+ facetFields.addFields(doc, paths);
+ indexWriter.addDocument(doc);
+ }
+
+ /** Build the example index. */
+ private void index() throws IOException {
+ IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER,
+ new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER)));
+
+ // Writes facet ords to a separate directory from the main index
+ DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir, IndexWriterConfig.OpenMode.CREATE);
+
+ // Reused across documents, to add the necessary facet fields
+ FacetFields facetFields = new FacetFields(taxoWriter, indexingParams);
+
+ 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");
+
+ indexWriter.close();
+ taxoWriter.close();
+ }
+
+ /** User runs a query and counts facets. */
+ private List<FacetResult> search() throws IOException {
+ DirectoryReader indexReader = DirectoryReader.open(indexDir);
+ IndexSearcher searcher = new IndexSearcher(indexReader);
+ TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
+
+ // Count both "Publish Date" and "Author" dimensions
+ FacetSearchParams fsp = new FacetSearchParams(indexingParams,
+ new CountFacetRequest(new CategoryPath("Publish Date"), 10),
+ new CountFacetRequest(new CategoryPath("Author"), 10));
+
+ // Aggregatses the facet counts
+ FacetsCollector fc = FacetsCollector.create(fsp, searcher.getIndexReader(), taxoReader);
+
+ // 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);
+
+ // Retrieve results
+ List<FacetResult> facetResults = fc.getFacetResults();
+
+ indexReader.close();
+ taxoReader.close();
+
+ return facetResults;
+ }
+
+ /** Runs the search example. */
+ public List<FacetResult> runSearch() throws IOException {
+ index();
+ return search();
+ }
+
+ /** Runs the search example and prints the results. */
+ public static void main(String[] args) throws Exception {
+ System.out.println("Facet counting over multiple category lists example:");
+ System.out.println("-----------------------");
+ List<FacetResult> results = new MultiCategoryListsFacetsExample().runSearch();
+ for (FacetResult res : results) {
+ System.out.println(res);
+ }
+ }
+
+}
Added: lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleFacetsExample.java?rev=1444538&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleFacetsExample.java (added)
+++ lucene/dev/trunk/lucene/demo/src/java/org/apache/lucene/demo/facet/SimpleFacetsExample.java Sun Feb 10 12:55:40 2013
@@ -0,0 +1,166 @@
+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.CategoryPath;
+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
+ * 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.
+ */
+
+/** Shows simple usage of faceted indexing and search. */
+public class SimpleFacetsExample {
+
+ private final Directory indexDir = new RAMDirectory();
+ private final Directory taxoDir = new RAMDirectory();
+
+ /** Empty constructor */
+ public SimpleFacetsExample() {}
+
+ private void add(IndexWriter indexWriter, FacetFields facetFields, String ... categoryPaths) throws IOException {
+ Document doc = new Document();
+
+ List<CategoryPath> paths = new ArrayList<CategoryPath>();
+ for (String categoryPath : categoryPaths) {
+ paths.add(new CategoryPath(categoryPath, '/'));
+ }
+ facetFields.addFields(doc, paths);
+ indexWriter.addDocument(doc);
+ }
+
+ /** Build the example index. */
+ private void index() throws IOException {
+ IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER,
+ new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER)));
+
+ // Writes facet ords to a separate directory from the main index
+ DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir, IndexWriterConfig.OpenMode.CREATE);
+
+ // Reused across documents, to add the necessary facet fields
+ FacetFields facetFields = new FacetFields(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");
+
+ indexWriter.close();
+ taxoWriter.close();
+ }
+
+ /** User runs a query and counts facets. */
+ private List<FacetResult> search() throws IOException {
+ DirectoryReader indexReader = DirectoryReader.open(indexDir);
+ IndexSearcher searcher = new IndexSearcher(indexReader);
+ TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
+
+ // Count both "Publish Date" and "Author" dimensions
+ FacetSearchParams fsp = new FacetSearchParams(
+ new CountFacetRequest(new CategoryPath("Publish Date"), 10),
+ new CountFacetRequest(new CategoryPath("Author"), 10));
+
+ // Aggregatses the facet counts
+ FacetsCollector fc = FacetsCollector.create(fsp, searcher.getIndexReader(), taxoReader);
+
+ // 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);
+
+ // Retrieve results
+ List<FacetResult> facetResults = fc.getFacetResults();
+
+ indexReader.close();
+ taxoReader.close();
+
+ return facetResults;
+ }
+
+ /** User drills down on 'Publish date/2010'. */
+ private List<FacetResult> 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 CategoryPath("Author"), 10));
+ DrillDownQuery q = new DrillDownQuery(fsp.indexingParams, new MatchAllDocsQuery());
+ q.add(new CategoryPath("Publish Date/2010", '/'));
+ FacetsCollector fc = FacetsCollector.create(fsp, searcher.getIndexReader(), taxoReader);
+ searcher.search(q, fc);
+
+ // Retrieve results
+ List<FacetResult> facetResults = fc.getFacetResults();
+
+ indexReader.close();
+ taxoReader.close();
+
+ return facetResults;
+ }
+
+ /** Runs the search example. */
+ public List<FacetResult> runSearch() throws IOException {
+ index();
+ return search();
+ }
+
+ /** Runs the drill-down example. */
+ public List<FacetResult> runDrillDown() throws IOException {
+ index();
+ return drillDown();
+ }
+
+ /** 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:");
+ System.out.println("-----------------------");
+ List<FacetResult> results = new SimpleFacetsExample().runSearch();
+ for (FacetResult res : results) {
+ System.out.println(res);
+ }
+
+ 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);
+ }
+ }
+
+}
Added: lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java?rev=1444538&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java (added)
+++ lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java Sun Feb 10 12:55:40 2013
@@ -0,0 +1,50 @@
+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
+ * 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.
+ */
+
+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 {
+ assertExampleResult(new AssociationsFacetsExample().runSumIntAssociations(), EXPECTED_INT_SUM_RESULTS);
+ assertExampleResult(new AssociationsFacetsExample().runSumFloatAssociations(), EXPECTED_FLOAT_SUM_RESULTS);
+ }
+
+ private void assertExampleResult(List<FacetResult> res, double[] expectedResults) {
+ assertNotNull("Null result!", res);
+ assertEquals("Wrong number of results!", 1, res.size());
+ assertEquals("Wrong number of facets!", 2, res.get(0).getNumValidDescendants());
+
+ Iterable<? extends FacetResultNode> it = res.get(0).getFacetResultNode().subResults;
+ int i = 0;
+ for (FacetResultNode fResNode : it) {
+ assertEquals("Wrong result for facet "+fResNode.label, expectedResults[i++], fResNode.value, 1E-5);
+ }
+ }
+
+}
Added: lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java?rev=1444538&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java (added)
+++ lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java Sun Feb 10 12:55:40 2013
@@ -0,0 +1,58 @@
+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.CategoryPath;
+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
+ * 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.
+ */
+
+public class TestMultiCategoryListsFacetsExample extends LuceneTestCase {
+
+ private static final ObjectToIntMap<CategoryPath> expectedCounts = new ObjectToIntMap<CategoryPath>();
+ static {
+ expectedCounts.put(new CategoryPath("Publish Date", "2012"), 2);
+ expectedCounts.put(new CategoryPath("Publish Date", "2010"), 2);
+ expectedCounts.put(new CategoryPath("Publish Date", "1999"), 1);
+ expectedCounts.put(new CategoryPath("Author", "Lisa"), 2);
+ expectedCounts.put(new CategoryPath("Author", "Frank"), 1);
+ expectedCounts.put(new CategoryPath("Author", "Susan"), 1);
+ expectedCounts.put(new CategoryPath("Author", "Bob"), 1);
+ }
+
+ private void assertExpectedCounts(List<FacetResult> facetResults, ObjectToIntMap<CategoryPath> 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 testExample() throws Exception {
+ List<FacetResult> facetResults = new MultiCategoryListsFacetsExample().runSearch();
+ assertEquals(2, facetResults.size());
+ assertExpectedCounts(facetResults, expectedCounts);
+ }
+
+}
Added: lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java?rev=1444538&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java (added)
+++ lucene/dev/trunk/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java Sun Feb 10 12:55:40 2013
@@ -0,0 +1,71 @@
+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.CategoryPath;
+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
+ * 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.
+ */
+
+public class TestSimpleFacetsExample extends LuceneTestCase {
+
+ private static final ObjectToIntMap<CategoryPath> expectedCounts = new ObjectToIntMap<CategoryPath>();
+ static {
+ expectedCounts.put(new CategoryPath("Publish Date", "2012"), 2);
+ expectedCounts.put(new CategoryPath("Publish Date", "2010"), 2);
+ expectedCounts.put(new CategoryPath("Publish Date", "1999"), 1);
+ expectedCounts.put(new CategoryPath("Author", "Lisa"), 2);
+ expectedCounts.put(new CategoryPath("Author", "Frank"), 1);
+ expectedCounts.put(new CategoryPath("Author", "Susan"), 1);
+ expectedCounts.put(new CategoryPath("Author", "Bob"), 1);
+ }
+
+ private static final ObjectToIntMap<CategoryPath> expectedCountsDrillDown = new ObjectToIntMap<CategoryPath>();
+ static {
+ expectedCountsDrillDown.put(new CategoryPath("Author", "Lisa"), 1);
+ expectedCountsDrillDown.put(new CategoryPath("Author", "Bob"), 1);
+ }
+
+ private void assertExpectedCounts(List<FacetResult> facetResults, ObjectToIntMap<CategoryPath> 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<FacetResult> facetResults = new SimpleFacetsExample().runSearch();
+ assertEquals(2, facetResults.size());
+ assertExpectedCounts(facetResults, expectedCounts);
+ }
+
+ @Test
+ public void testDrillDown() throws Exception {
+ List<FacetResult> facetResults = new SimpleFacetsExample().runDrillDown();
+ assertEquals(1, facetResults.size());
+ assertExpectedCounts(facetResults, expectedCountsDrillDown);
+ }
+
+}