001 package org.apache.lucene.demo.facet;
002
003 import java.io.IOException;
004 import java.util.ArrayList;
005 import java.util.HashMap;
006 import java.util.List;
007 import java.util.Map;
008
009 import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
010 import org.apache.lucene.document.Document;
011 import org.apache.lucene.facet.index.FacetFields;
012 import org.apache.lucene.facet.params.CategoryListParams;
013 import org.apache.lucene.facet.params.FacetIndexingParams;
014 import org.apache.lucene.facet.params.FacetSearchParams;
015 import org.apache.lucene.facet.params.PerDimensionIndexingParams;
016 import org.apache.lucene.facet.search.CountFacetRequest;
017 import org.apache.lucene.facet.search.FacetResult;
018 import org.apache.lucene.facet.search.FacetsCollector;
019 import org.apache.lucene.facet.taxonomy.CategoryPath;
020 import org.apache.lucene.facet.taxonomy.TaxonomyReader;
021 import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
022 import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
023 import org.apache.lucene.index.DirectoryReader;
024 import org.apache.lucene.index.IndexWriter;
025 import org.apache.lucene.index.IndexWriterConfig;
026 import org.apache.lucene.search.IndexSearcher;
027 import org.apache.lucene.search.MatchAllDocsQuery;
028 import org.apache.lucene.store.Directory;
029 import org.apache.lucene.store.RAMDirectory;
030
031 /*
032 * Licensed to the Apache Software Foundation (ASF) under one or more
033 * contributor license agreements. See the NOTICE file distributed with
034 * this work for additional information regarding copyright ownership.
035 * The ASF licenses this file to You under the Apache License, Version 2.0
036 * (the "License"); you may not use this file except in compliance with
037 * the License. You may obtain a copy of the License at
038 *
039 * http://www.apache.org/licenses/LICENSE-2.0
040 *
041 * Unless required by applicable law or agreed to in writing, software
042 * distributed under the License is distributed on an "AS IS" BASIS,
043 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
044 * See the License for the specific language governing permissions and
045 * limitations under the License.
046 */
047
048 /** Demonstrates indexing categories into different category lists. */
049 public class MultiCategoryListsFacetsExample {
050
051 private final FacetIndexingParams indexingParams;
052 private final Directory indexDir = new RAMDirectory();
053 private final Directory taxoDir = new RAMDirectory();
054
055 /** Creates a new instance and populates the catetory list params mapping. */
056 public MultiCategoryListsFacetsExample() {
057 // index all Author facets in one category list and all Publish Date in another.
058 Map<CategoryPath,CategoryListParams> categoryListParams = new HashMap<CategoryPath,CategoryListParams>();
059 categoryListParams.put(new CategoryPath("Author"), new CategoryListParams("author"));
060 categoryListParams.put(new CategoryPath("Publish Date"), new CategoryListParams("pubdate"));
061 indexingParams = new PerDimensionIndexingParams(categoryListParams);
062 }
063
064 private void add(IndexWriter indexWriter, FacetFields facetFields, String ... categoryPaths) throws IOException {
065 Document doc = new Document();
066
067 List<CategoryPath> paths = new ArrayList<CategoryPath>();
068 for (String categoryPath : categoryPaths) {
069 paths.add(new CategoryPath(categoryPath, '/'));
070 }
071 facetFields.addFields(doc, paths);
072 indexWriter.addDocument(doc);
073 }
074
075 /** Build the example index. */
076 private void index() throws IOException {
077 IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER,
078 new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER)));
079
080 // Writes facet ords to a separate directory from the main index
081 DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir);
082
083 // Reused across documents, to add the necessary facet fields
084 FacetFields facetFields = new FacetFields(taxoWriter, indexingParams);
085
086 add(indexWriter, facetFields, "Author/Bob", "Publish Date/2010/10/15");
087 add(indexWriter, facetFields, "Author/Lisa", "Publish Date/2010/10/20");
088 add(indexWriter, facetFields, "Author/Lisa", "Publish Date/2012/1/1");
089 add(indexWriter, facetFields, "Author/Susan", "Publish Date/2012/1/7");
090 add(indexWriter, facetFields, "Author/Frank", "Publish Date/1999/5/5");
091
092 indexWriter.close();
093 taxoWriter.close();
094 }
095
096 /** User runs a query and counts facets. */
097 private List<FacetResult> search() throws IOException {
098 DirectoryReader indexReader = DirectoryReader.open(indexDir);
099 IndexSearcher searcher = new IndexSearcher(indexReader);
100 TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
101
102 // Count both "Publish Date" and "Author" dimensions
103 FacetSearchParams fsp = new FacetSearchParams(indexingParams,
104 new CountFacetRequest(new CategoryPath("Publish Date"), 10),
105 new CountFacetRequest(new CategoryPath("Author"), 10));
106
107 // Aggregatses the facet counts
108 FacetsCollector fc = FacetsCollector.create(fsp, searcher.getIndexReader(), taxoReader);
109
110 // MatchAllDocsQuery is for "browsing" (counts facets
111 // for all non-deleted docs in the index); normally
112 // you'd use a "normal" query, and use MultiCollector to
113 // wrap collecting the "normal" hits and also facets:
114 searcher.search(new MatchAllDocsQuery(), fc);
115
116 // Retrieve results
117 List<FacetResult> facetResults = fc.getFacetResults();
118
119 indexReader.close();
120 taxoReader.close();
121
122 return facetResults;
123 }
124
125 /** Runs the search example. */
126 public List<FacetResult> runSearch() throws IOException {
127 index();
128 return search();
129 }
130
131 /** Runs the search example and prints the results. */
132 public static void main(String[] args) throws Exception {
133 System.out.println("Facet counting over multiple category lists example:");
134 System.out.println("-----------------------");
135 List<FacetResult> results = new MultiCategoryListsFacetsExample().runSearch();
136 for (FacetResult res : results) {
137 System.out.println(res);
138 }
139 }
140
141 }