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.DrillDownQuery;
027    import org.apache.lucene.facet.FacetField;
028    import org.apache.lucene.facet.FacetResult;
029    import org.apache.lucene.facet.Facets;
030    import org.apache.lucene.facet.FacetsCollector;
031    import org.apache.lucene.facet.FacetsConfig;
032    import org.apache.lucene.facet.taxonomy.FastTaxonomyFacetCounts;
033    import org.apache.lucene.facet.taxonomy.TaxonomyReader;
034    import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
035    import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
036    import org.apache.lucene.index.DirectoryReader;
037    import org.apache.lucene.index.IndexWriter;
038    import org.apache.lucene.index.IndexWriterConfig;
039    import org.apache.lucene.search.IndexSearcher;
040    import org.apache.lucene.search.MatchAllDocsQuery;
041    import org.apache.lucene.store.Directory;
042    import org.apache.lucene.store.RAMDirectory;
043    
044    /** Shows simple usage of faceted indexing and search. */
045    public class SimpleFacetsExample {
046    
047      private final Directory indexDir = new RAMDirectory();
048      private final Directory taxoDir = new RAMDirectory();
049      private final FacetsConfig config = new FacetsConfig();
050    
051      /** Empty constructor */
052      public SimpleFacetsExample() {
053        config.setHierarchical("Publish Date", true);
054      }
055      
056      /** Build the example index. */
057      private void index() throws IOException {
058        IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER, 
059            new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER)));
060    
061        // Writes facet ords to a separate directory from the main index
062        DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir);
063    
064        Document doc = new Document();
065        doc.add(new FacetField("Author", "Bob"));
066        doc.add(new FacetField("Publish Date", "2010", "10", "15"));
067        indexWriter.addDocument(config.build(taxoWriter, doc));
068    
069        doc = new Document();
070        doc.add(new FacetField("Author", "Lisa"));
071        doc.add(new FacetField("Publish Date", "2010", "10", "20"));
072        indexWriter.addDocument(config.build(taxoWriter, doc));
073    
074        doc = new Document();
075        doc.add(new FacetField("Author", "Lisa"));
076        doc.add(new FacetField("Publish Date", "2012", "1", "1"));
077        indexWriter.addDocument(config.build(taxoWriter, doc));
078    
079        doc = new Document();
080        doc.add(new FacetField("Author", "Susan"));
081        doc.add(new FacetField("Publish Date", "2012", "1", "7"));
082        indexWriter.addDocument(config.build(taxoWriter, doc));
083    
084        doc = new Document();
085        doc.add(new FacetField("Author", "Frank"));
086        doc.add(new FacetField("Publish Date", "1999", "5", "5"));
087        indexWriter.addDocument(config.build(taxoWriter, doc));
088        
089        indexWriter.close();
090        taxoWriter.close();
091      }
092    
093      /** User runs a query and counts facets. */
094      private List<FacetResult> search() throws IOException {
095        DirectoryReader indexReader = DirectoryReader.open(indexDir);
096        IndexSearcher searcher = new IndexSearcher(indexReader);
097        TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
098    
099        FacetsCollector fc = new FacetsCollector();
100    
101        // MatchAllDocsQuery is for "browsing" (counts facets
102        // for all non-deleted docs in the index); normally
103        // you'd use a "normal" query:
104        FacetsCollector.search(searcher, new MatchAllDocsQuery(), 10, fc);
105    
106        // Retrieve results
107        List<FacetResult> results = new ArrayList<FacetResult>();
108    
109        // Count both "Publish Date" and "Author" dimensions
110        Facets facets = new FastTaxonomyFacetCounts(taxoReader, config, fc);
111        results.add(facets.getTopChildren(10, "Author"));
112        results.add(facets.getTopChildren(10, "Publish Date"));
113        
114        indexReader.close();
115        taxoReader.close();
116        
117        return results;
118      }
119      
120      /** User drills down on 'Publish Date/2010'. */
121      private FacetResult drillDown() throws IOException {
122        DirectoryReader indexReader = DirectoryReader.open(indexDir);
123        IndexSearcher searcher = new IndexSearcher(indexReader);
124        TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
125    
126        // Passing no baseQuery means we drill down on all
127        // documents ("browse only"):
128        DrillDownQuery q = new DrillDownQuery(config);
129    
130        // Now user drills down on Publish Date/2010:
131        q.add("Publish Date", "2010");
132        FacetsCollector fc = new FacetsCollector();
133        FacetsCollector.search(searcher, q, 10, fc);
134    
135        // Retrieve results
136        Facets facets = new FastTaxonomyFacetCounts(taxoReader, config, fc);
137        FacetResult result = facets.getTopChildren(10, "Author");
138    
139        indexReader.close();
140        taxoReader.close();
141        
142        return result;
143      }
144    
145      /** Runs the search example. */
146      public List<FacetResult> runSearch() throws IOException {
147        index();
148        return search();
149      }
150      
151      /** Runs the drill-down example. */
152      public FacetResult runDrillDown() throws IOException {
153        index();
154        return drillDown();
155      }
156    
157      /** Runs the search and drill-down examples and prints the results. */
158      public static void main(String[] args) throws Exception {
159        System.out.println("Facet counting example:");
160        System.out.println("-----------------------");
161        SimpleFacetsExample example = new SimpleFacetsExample();
162        List<FacetResult> results = example.runSearch();
163        System.out.println("Author: " + results.get(0));
164        System.out.println("Publish Date: " + results.get(1));
165    
166        System.out.println("\n");
167        System.out.println("Facet drill-down example (Publish Date/2010):");
168        System.out.println("---------------------------------------------");
169        System.out.println("Author: " + example.runDrillDown());
170      }
171      
172    }