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