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.FacetResult;
028 import org.apache.lucene.facet.Facets;
029 import org.apache.lucene.facet.FacetsCollector;
030 import org.apache.lucene.facet.FacetsConfig;
031 import org.apache.lucene.facet.taxonomy.FloatAssociationFacetField;
032 import org.apache.lucene.facet.taxonomy.IntAssociationFacetField;
033 import org.apache.lucene.facet.taxonomy.TaxonomyFacetSumFloatAssociations;
034 import org.apache.lucene.facet.taxonomy.TaxonomyFacetSumIntAssociations;
035 import org.apache.lucene.facet.taxonomy.TaxonomyReader;
036 import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
037 import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
038 import org.apache.lucene.index.DirectoryReader;
039 import org.apache.lucene.index.IndexWriter;
040 import org.apache.lucene.index.IndexWriterConfig;
041 import org.apache.lucene.search.IndexSearcher;
042 import org.apache.lucene.search.MatchAllDocsQuery;
043 import org.apache.lucene.store.Directory;
044 import org.apache.lucene.store.RAMDirectory;
045
046 /** Shows example usage of category associations. */
047 public class AssociationsFacetsExample {
048
049 private final Directory indexDir = new RAMDirectory();
050 private final Directory taxoDir = new RAMDirectory();
051 private final FacetsConfig config;
052
053 /** Empty constructor */
054 public AssociationsFacetsExample() {
055 config = new FacetsConfig();
056 config.setMultiValued("tags", true);
057 config.setIndexFieldName("tags", "$tags");
058 config.setMultiValued("genre", true);
059 config.setIndexFieldName("genre", "$genre");
060 }
061
062 /** Build the example index. */
063 private void index() throws IOException {
064 IndexWriterConfig iwc = new IndexWriterConfig(FacetExamples.EXAMPLES_VER,
065 new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER));
066 IndexWriter indexWriter = new IndexWriter(indexDir, iwc);
067
068 // Writes facet ords to a separate directory from the main index
069 DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir);
070
071 Document doc = new Document();
072 // 3 occurrences for tag 'lucene'
073 doc.add(new IntAssociationFacetField(3, "tags", "lucene"));
074 // 87% confidence level of genre 'computing'
075 doc.add(new FloatAssociationFacetField(0.87f, "genre", "computing"));
076 indexWriter.addDocument(config.build(taxoWriter, doc));
077
078 doc = new Document();
079 // 1 occurrence for tag 'lucene'
080 doc.add(new IntAssociationFacetField(1, "tags", "lucene"));
081 // 2 occurrence for tag 'solr'
082 doc.add(new IntAssociationFacetField(2, "tags", "solr"));
083 // 75% confidence level of genre 'computing'
084 doc.add(new FloatAssociationFacetField(0.75f, "genre", "computing"));
085 // 34% confidence level of genre 'software'
086 doc.add(new FloatAssociationFacetField(0.34f, "genre", "software"));
087 indexWriter.addDocument(config.build(taxoWriter, doc));
088
089 indexWriter.close();
090 taxoWriter.close();
091 }
092
093 /** User runs a query and aggregates facets by summing their association values. */
094 private List<FacetResult> sumAssociations() 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 Facets tags = new TaxonomyFacetSumIntAssociations("$tags", taxoReader, config, fc);
107 Facets genre = new TaxonomyFacetSumFloatAssociations("$genre", taxoReader, config, fc);
108
109 // Retrieve results
110 List<FacetResult> results = new ArrayList<FacetResult>();
111 results.add(tags.getTopChildren(10, "tags"));
112 results.add(genre.getTopChildren(10, "genre"));
113
114 indexReader.close();
115 taxoReader.close();
116
117 return results;
118 }
119
120 /** User drills down on 'tags/solr'. */
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("tags", "solr");
132 FacetsCollector fc = new FacetsCollector();
133 FacetsCollector.search(searcher, q, 10, fc);
134
135 // Retrieve results
136 Facets facets = new TaxonomyFacetSumFloatAssociations("$genre", taxoReader, config, fc);
137 FacetResult result = facets.getTopChildren(10, "genre");
138
139 indexReader.close();
140 taxoReader.close();
141
142 return result;
143 }
144
145 /** Runs summing association example. */
146 public List<FacetResult> runSumAssociations() throws IOException {
147 index();
148 return sumAssociations();
149 }
150
151 /** Runs the drill-down example. */
152 public FacetResult runDrillDown() throws IOException {
153 index();
154 return drillDown();
155 }
156
157 /** Runs the sum int/float associations examples and prints the results. */
158 public static void main(String[] args) throws Exception {
159 System.out.println("Sum associations example:");
160 System.out.println("-------------------------");
161 List<FacetResult> results = new AssociationsFacetsExample().runSumAssociations();
162 System.out.println("tags: " + results.get(0));
163 System.out.println("genre: " + results.get(1));
164 }
165 }