001package org.apache.lucene.demo.facet; 002 003import java.io.IOException; 004import java.util.ArrayList; 005import java.util.HashMap; 006import java.util.List; 007import java.util.Map; 008 009import org.apache.lucene.analysis.core.WhitespaceAnalyzer; 010import org.apache.lucene.document.Document; 011import org.apache.lucene.facet.index.FacetFields; 012import org.apache.lucene.facet.params.CategoryListParams; 013import org.apache.lucene.facet.params.FacetIndexingParams; 014import org.apache.lucene.facet.params.FacetSearchParams; 015import org.apache.lucene.facet.params.PerDimensionIndexingParams; 016import org.apache.lucene.facet.search.CountFacetRequest; 017import org.apache.lucene.facet.search.FacetResult; 018import org.apache.lucene.facet.search.FacetsCollector; 019import org.apache.lucene.facet.taxonomy.CategoryPath; 020import org.apache.lucene.facet.taxonomy.TaxonomyReader; 021import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; 022import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter; 023import org.apache.lucene.index.DirectoryReader; 024import org.apache.lucene.index.IndexWriter; 025import org.apache.lucene.index.IndexWriterConfig; 026import org.apache.lucene.search.IndexSearcher; 027import org.apache.lucene.search.MatchAllDocsQuery; 028import org.apache.lucene.store.Directory; 029import 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. */ 049public 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, IndexWriterConfig.OpenMode.CREATE); 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}