001 package org.apache.lucene.demo.facet; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more 005 * contributor license agreements. See the NOTICE file distributed with 006 * this work for additional information regarding copyright ownership. 007 * The ASF licenses this file to You under the Apache License, Version 2.0 008 * (the "License"); you may not use this file except in compliance with 009 * the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 import java.io.IOException; 021 import java.util.ArrayList; 022 import java.util.List; 023 024 import org.apache.lucene.analysis.core.WhitespaceAnalyzer; 025 import org.apache.lucene.document.Document; 026 import org.apache.lucene.facet.params.FacetSearchParams; 027 import org.apache.lucene.facet.search.CountFacetRequest; 028 import org.apache.lucene.facet.search.DrillDownQuery; 029 import org.apache.lucene.facet.search.FacetResult; 030 import org.apache.lucene.facet.search.FacetsCollector; 031 import org.apache.lucene.facet.sortedset.SortedSetDocValuesAccumulator; 032 import org.apache.lucene.facet.sortedset.SortedSetDocValuesFacetFields; 033 import org.apache.lucene.facet.sortedset.SortedSetDocValuesReaderState; 034 import org.apache.lucene.facet.taxonomy.CategoryPath; 035 import org.apache.lucene.index.DirectoryReader; 036 import org.apache.lucene.index.IndexWriter; 037 import org.apache.lucene.index.IndexWriterConfig; 038 import org.apache.lucene.search.IndexSearcher; 039 import org.apache.lucene.search.MatchAllDocsQuery; 040 import org.apache.lucene.store.Directory; 041 import org.apache.lucene.store.RAMDirectory; 042 043 /** Shows simple usage of faceted indexing and search, 044 * using {@link SortedSetDocValuesFacetFields} and {@link 045 * SortedSetDocValuesAccumulator}. */ 046 047 public class SimpleSortedSetFacetsExample { 048 049 private final Directory indexDir = new RAMDirectory(); 050 051 /** Empty constructor */ 052 public SimpleSortedSetFacetsExample() {} 053 054 private void add(IndexWriter indexWriter, SortedSetDocValuesFacetFields facetFields, String ... categoryPaths) throws IOException { 055 Document doc = new Document(); 056 057 List<CategoryPath> paths = new ArrayList<CategoryPath>(); 058 for (String categoryPath : categoryPaths) { 059 paths.add(new CategoryPath(categoryPath, '/')); 060 } 061 facetFields.addFields(doc, paths); 062 indexWriter.addDocument(doc); 063 } 064 065 /** Build the example index. */ 066 private void index() throws IOException { 067 IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER, 068 new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER))); 069 070 // Reused across documents, to add the necessary facet fields 071 SortedSetDocValuesFacetFields facetFields = new SortedSetDocValuesFacetFields(); 072 073 add(indexWriter, facetFields, "Author/Bob", "Publish Year/2010"); 074 add(indexWriter, facetFields, "Author/Lisa", "Publish Year/2010"); 075 add(indexWriter, facetFields, "Author/Lisa", "Publish Year/2012"); 076 add(indexWriter, facetFields, "Author/Susan", "Publish Year/2012"); 077 add(indexWriter, facetFields, "Author/Frank", "Publish Year/1999"); 078 079 indexWriter.close(); 080 } 081 082 /** User runs a query and counts facets. */ 083 private List<FacetResult> search() throws IOException { 084 DirectoryReader indexReader = DirectoryReader.open(indexDir); 085 IndexSearcher searcher = new IndexSearcher(indexReader); 086 SortedSetDocValuesReaderState state = new SortedSetDocValuesReaderState(indexReader); 087 088 // Count both "Publish Year" and "Author" dimensions 089 FacetSearchParams fsp = new FacetSearchParams( 090 new CountFacetRequest(new CategoryPath("Publish Year"), 10), 091 new CountFacetRequest(new CategoryPath("Author"), 10)); 092 093 // Aggregatses the facet counts 094 FacetsCollector fc = FacetsCollector.create(new SortedSetDocValuesAccumulator(state, fsp)); 095 096 // MatchAllDocsQuery is for "browsing" (counts facets 097 // for all non-deleted docs in the index); normally 098 // you'd use a "normal" query, and use MultiCollector to 099 // wrap collecting the "normal" hits and also facets: 100 searcher.search(new MatchAllDocsQuery(), fc); 101 102 // Retrieve results 103 List<FacetResult> facetResults = fc.getFacetResults(); 104 105 indexReader.close(); 106 107 return facetResults; 108 } 109 110 /** User drills down on 'Publish Year/2010'. */ 111 private List<FacetResult> drillDown() throws IOException { 112 DirectoryReader indexReader = DirectoryReader.open(indexDir); 113 IndexSearcher searcher = new IndexSearcher(indexReader); 114 SortedSetDocValuesReaderState state = new SortedSetDocValuesReaderState(indexReader); 115 116 // Now user drills down on Publish Year/2010: 117 FacetSearchParams fsp = new FacetSearchParams(new CountFacetRequest(new CategoryPath("Author"), 10)); 118 DrillDownQuery q = new DrillDownQuery(fsp.indexingParams, new MatchAllDocsQuery()); 119 q.add(new CategoryPath("Publish Year/2010", '/')); 120 FacetsCollector fc = FacetsCollector.create(new SortedSetDocValuesAccumulator(state, fsp)); 121 searcher.search(q, fc); 122 123 // Retrieve results 124 List<FacetResult> facetResults = fc.getFacetResults(); 125 126 indexReader.close(); 127 128 return facetResults; 129 } 130 131 /** Runs the search example. */ 132 public List<FacetResult> runSearch() throws IOException { 133 index(); 134 return search(); 135 } 136 137 /** Runs the drill-down example. */ 138 public List<FacetResult> runDrillDown() throws IOException { 139 index(); 140 return drillDown(); 141 } 142 143 /** Runs the search and drill-down examples and prints the results. */ 144 public static void main(String[] args) throws Exception { 145 System.out.println("Facet counting example:"); 146 System.out.println("-----------------------"); 147 List<FacetResult> results = new SimpleSortedSetFacetsExample().runSearch(); 148 for (FacetResult res : results) { 149 System.out.println(res); 150 } 151 152 System.out.println("\n"); 153 System.out.println("Facet drill-down example (Publish Year/2010):"); 154 System.out.println("---------------------------------------------"); 155 results = new SimpleSortedSetFacetsExample().runDrillDown(); 156 for (FacetResult res : results) { 157 System.out.println(res); 158 } 159 } 160 161 }