package org.apache.lucene.facet.example.simple;
import java.util.Iterator;
import java.util.List;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.search.MultiCollector;
import org.apache.lucene.facet.example.ExampleUtils;
import org.apache.lucene.facet.index.params.DefaultFacetIndexingParams;
import org.apache.lucene.facet.index.params.FacetIndexingParams;
import org.apache.lucene.facet.search.DrillDown;
import org.apache.lucene.facet.search.FacetsCollector;
import org.apache.lucene.facet.search.params.CountFacetRequest;
import org.apache.lucene.facet.search.params.FacetRequest;
import org.apache.lucene.facet.search.params.FacetSearchParams;
import org.apache.lucene.facet.search.results.FacetResult;
import org.apache.lucene.facet.search.results.FacetResultNode;
import org.apache.lucene.facet.taxonomy.CategoryPath;
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* SampleSearcer searches index with facets.
*
* @lucene.experimental
*/
public class SimpleSearcher {
/**
* Search an index with facets.
* @param indexReader index reader.
* @param taxoReader taxonomy reader.
* @throws Exception on error (no detailed exception handling here for sample simplicity
* @return facet results
*/
public static List<FacetResult> searchWithFacets (IndexReader indexReader,
TaxonomyReader taxoReader) throws Exception {
CountFacetRequest facetRequest = new CountFacetRequest(new CategoryPath("root","a"), 10);
return searchWithRequest(indexReader, taxoReader, null, facetRequest);
}
/**
* Search an index with facets for given facet requests.
* @param indexReader index reader.
* @param taxoReader taxonomy reader.
* @param indexingParams the facet indexing params
* @param facetRequests facet requests of interest
* @throws Exception on error (no detailed exception handling here for sample simplicity
* @return facet results
*/
public static List<FacetResult> searchWithRequest(IndexReader indexReader,
TaxonomyReader taxoReader, FacetIndexingParams indexingParams,
FacetRequest... facetRequests) throws Exception {
Query q = new TermQuery(new Term(SimpleUtils.TEXT, "white"));
return searchWithRequestAndQuery(q, indexReader, taxoReader,
indexingParams, facetRequests);
}
/**
* Search an index with facets for given query and facet requests.
* @param q query of interest
* @param indexReader index reader.
* @param taxoReader taxonomy reader.
* @param indexingParams the facet indexing params
* @param facetRequests facet requests of interest
* @throws Exception on error (no detailed exception handling here for sample simplicity
* @return facet results
*/
public static List<FacetResult> searchWithRequestAndQuery(Query q,
IndexReader indexReader, TaxonomyReader taxoReader,
FacetIndexingParams indexingParams, FacetRequest... facetRequests)
throws Exception {
ExampleUtils.log("Query: " + q);
// prepare searcher to search against
IndexSearcher searcher = new IndexSearcher(indexReader);
// collect matching documents into a collector
TopScoreDocCollector topDocsCollector = TopScoreDocCollector.create(10, true);
if (indexingParams == null) {
indexingParams = new DefaultFacetIndexingParams();
}
// Faceted search parameters indicate which facets are we interested in
FacetSearchParams facetSearchParams = new FacetSearchParams(indexingParams);
// Add the facet requests of interest to the search params
for (FacetRequest frq : facetRequests) {
facetSearchParams.addFacetRequest(frq);
}
FacetsCollector facetsCollector = new FacetsCollector(facetSearchParams, indexReader, taxoReader);
// perform documents search and facets accumulation
searcher.search(q, MultiCollector.wrap(topDocsCollector, facetsCollector));
// Obtain facets results and print them
List<FacetResult> res = facetsCollector.getFacetResults();
int i = 0;
for (FacetResult facetResult : res) {
ExampleUtils.log("Res " + (i++) + ": " + facetResult);
}
return res;
}
/**
* Search an index with facets drill-down.
* @param indexReader index reader.
* @param taxoReader taxonomy reader.
* @throws Exception on error (no detailed exception handling here for sample simplicity
* @return facet results
*/
public static List<FacetResult> searchWithDrillDown(IndexReader indexReader,
TaxonomyReader taxoReader) throws Exception {
// base query the user is interested in
Query baseQuery = new TermQuery(new Term(SimpleUtils.TEXT, "white"));
// facet of interest
CountFacetRequest facetRequest = new CountFacetRequest(new CategoryPath("root","a"), 10);
// initial search - all docs matching the base query will contribute to the accumulation
List<FacetResult> res1 = searchWithRequest(indexReader, taxoReader, null, facetRequest);
// a single result (because there was a single request)
FacetResult fres = res1.get(0);
// assume the user is interested in the second sub-result
// (just take the second sub-result returned by the iterator - we know there are 3 results!)
Iterator<? extends FacetResultNode> resIterator = fres.getFacetResultNode().getSubResults().iterator();
resIterator.next(); // skip first result
CategoryPath categoryOfInterest = resIterator.next().getLabel();
// drill-down preparation: turn the base query into a drill-down query for the category of interest
Query q2 = DrillDown.query(baseQuery, categoryOfInterest);
// that's it - search with the new query and we're done!
// only documents both matching the base query AND containing the
// category of interest will contribute to the new accumulation
return searchWithRequestAndQuery(q2, indexReader, taxoReader, null, facetRequest);
}
}