mirror of https://github.com/apache/lucene.git
LUCENE-4762: improve facet examples
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1444538 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a20fbf7130
commit
71f295a69d
|
@ -0,0 +1,209 @@
|
|||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.facet.associations.AssociationFloatSumFacetRequest;
|
||||
import org.apache.lucene.facet.associations.AssociationIntSumFacetRequest;
|
||||
import org.apache.lucene.facet.associations.AssociationsFacetFields;
|
||||
import org.apache.lucene.facet.associations.CategoryAssociation;
|
||||
import org.apache.lucene.facet.associations.CategoryAssociationsContainer;
|
||||
import org.apache.lucene.facet.associations.CategoryFloatAssociation;
|
||||
import org.apache.lucene.facet.associations.CategoryIntAssociation;
|
||||
import org.apache.lucene.facet.index.FacetFields;
|
||||
import org.apache.lucene.facet.params.FacetSearchParams;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.search.FacetsAccumulator;
|
||||
import org.apache.lucene.facet.search.FacetsCollector;
|
||||
import org.apache.lucene.facet.search.StandardFacetsAccumulator;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** Shows example usage of category associations. */
|
||||
public class AssociationsFacetsExample {
|
||||
|
||||
/**
|
||||
* Categories per document, {@link #ASSOCIATIONS} hold the association value
|
||||
* for each category.
|
||||
*/
|
||||
public static CategoryPath[][] CATEGORIES = {
|
||||
// Doc #1
|
||||
{ new CategoryPath("tags", "lucene") ,
|
||||
new CategoryPath("genre", "computing")
|
||||
},
|
||||
|
||||
// Doc #2
|
||||
{ new CategoryPath("tags", "lucene"),
|
||||
new CategoryPath("tags", "solr"),
|
||||
new CategoryPath("genre", "computing"),
|
||||
new CategoryPath("genre", "software")
|
||||
}
|
||||
};
|
||||
|
||||
/** Association values for each category. */
|
||||
public static CategoryAssociation[][] ASSOCIATIONS = {
|
||||
// Doc #1 associations
|
||||
{
|
||||
/* 3 occurrences for tag 'lucene' */
|
||||
new CategoryIntAssociation(3),
|
||||
/* 87% confidence level of genre 'computing' */
|
||||
new CategoryFloatAssociation(0.87f)
|
||||
},
|
||||
|
||||
// Doc #2 associations
|
||||
{
|
||||
/* 1 occurrence for tag 'lucene' */
|
||||
new CategoryIntAssociation(1),
|
||||
/* 2 occurrences for tag 'solr' */
|
||||
new CategoryIntAssociation(2),
|
||||
/* 75% confidence level of genre 'computing' */
|
||||
new CategoryFloatAssociation(0.75f),
|
||||
/* 34% confidence level of genre 'software' */
|
||||
new CategoryFloatAssociation(0.34f),
|
||||
}
|
||||
};
|
||||
|
||||
private final Directory indexDir = new RAMDirectory();
|
||||
private final Directory taxoDir = new RAMDirectory();
|
||||
|
||||
/** Empty constructor */
|
||||
public AssociationsFacetsExample() {}
|
||||
|
||||
/** Build the example index. */
|
||||
private void index() throws IOException {
|
||||
IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER,
|
||||
new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER)));
|
||||
|
||||
// Writes facet ords to a separate directory from the main index
|
||||
DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir, IndexWriterConfig.OpenMode.CREATE);
|
||||
|
||||
// Reused across documents, to add the necessary facet fields
|
||||
FacetFields facetFields = new AssociationsFacetFields(taxoWriter);
|
||||
|
||||
for (int i = 0; i < CATEGORIES.length; i++) {
|
||||
Document doc = new Document();
|
||||
CategoryAssociationsContainer associations = new CategoryAssociationsContainer();
|
||||
for (int j = 0; j < CATEGORIES[i].length; j++) {
|
||||
associations.setAssociation(CATEGORIES[i][j], ASSOCIATIONS[i][j]);
|
||||
}
|
||||
facetFields.addFields(doc, associations);
|
||||
indexWriter.addDocument(doc);
|
||||
}
|
||||
|
||||
indexWriter.close();
|
||||
taxoWriter.close();
|
||||
}
|
||||
|
||||
/** User runs a query and aggregates facets by summing their int associations. */
|
||||
private List<FacetResult> sumIntAssociations() throws IOException {
|
||||
DirectoryReader indexReader = DirectoryReader.open(indexDir);
|
||||
IndexSearcher searcher = new IndexSearcher(indexReader);
|
||||
TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
|
||||
|
||||
// sum the 'tags' dimension
|
||||
FacetSearchParams fsp = new FacetSearchParams(new AssociationIntSumFacetRequest(new CategoryPath("tags"), 10));
|
||||
|
||||
FacetsAccumulator fa = new StandardFacetsAccumulator(fsp, indexReader, taxoReader);
|
||||
FacetsCollector fc = FacetsCollector.create(fa);
|
||||
|
||||
// MatchAllDocsQuery is for "browsing" (counts facets
|
||||
// for all non-deleted docs in the index); normally
|
||||
// you'd use a "normal" query, and use MultiCollector to
|
||||
// wrap collecting the "normal" hits and also facets:
|
||||
searcher.search(new MatchAllDocsQuery(), fc);
|
||||
|
||||
// Retrieve results
|
||||
List<FacetResult> facetResults = fc.getFacetResults();
|
||||
|
||||
indexReader.close();
|
||||
taxoReader.close();
|
||||
|
||||
return facetResults;
|
||||
}
|
||||
|
||||
/** User runs a query and aggregates facets by summing their float associations. */
|
||||
private List<FacetResult> sumFloatAssociations() throws IOException {
|
||||
DirectoryReader indexReader = DirectoryReader.open(indexDir);
|
||||
IndexSearcher searcher = new IndexSearcher(indexReader);
|
||||
TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
|
||||
|
||||
// sum the 'tags' dimension
|
||||
FacetSearchParams fsp = new FacetSearchParams(new AssociationFloatSumFacetRequest(new CategoryPath("genre"), 10));
|
||||
|
||||
FacetsAccumulator fa = new StandardFacetsAccumulator(fsp, indexReader, taxoReader);
|
||||
FacetsCollector fc = FacetsCollector.create(fa);
|
||||
|
||||
// MatchAllDocsQuery is for "browsing" (counts facets
|
||||
// for all non-deleted docs in the index); normally
|
||||
// you'd use a "normal" query, and use MultiCollector to
|
||||
// wrap collecting the "normal" hits and also facets:
|
||||
searcher.search(new MatchAllDocsQuery(), fc);
|
||||
|
||||
// Retrieve results
|
||||
List<FacetResult> facetResults = fc.getFacetResults();
|
||||
|
||||
indexReader.close();
|
||||
taxoReader.close();
|
||||
|
||||
return facetResults;
|
||||
}
|
||||
|
||||
/** Runs summing int association example. */
|
||||
public List<FacetResult> runSumIntAssociations() throws IOException {
|
||||
index();
|
||||
return sumIntAssociations();
|
||||
}
|
||||
|
||||
/** Runs summing float association example. */
|
||||
public List<FacetResult> runSumFloatAssociations() throws IOException {
|
||||
index();
|
||||
return sumFloatAssociations();
|
||||
}
|
||||
|
||||
/** Runs the sum int/float associations examples and prints the results. */
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Sum int-associations example:");
|
||||
System.out.println("-----------------------------");
|
||||
List<FacetResult> results = new AssociationsFacetsExample().runSumIntAssociations();
|
||||
for (FacetResult res : results) {
|
||||
System.out.println(res);
|
||||
}
|
||||
|
||||
System.out.println("\n");
|
||||
System.out.println("Sum float-associations example:");
|
||||
System.out.println("-------------------------------");
|
||||
results = new AssociationsFacetsExample().runSumFloatAssociations();
|
||||
for (FacetResult res : results) {
|
||||
System.out.println(res);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import org.apache.lucene.util.Version;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Simple utility functions for the faceting examples
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class ExampleUtils {
|
||||
|
||||
/** No instance */
|
||||
private ExampleUtils() {}
|
||||
|
||||
/**
|
||||
* True if the system property <code>tests.verbose</code> has been set.
|
||||
* If true, it causes {@link #log(Object)} to print messages to the console.
|
||||
*/
|
||||
public static final boolean VERBOSE = Boolean.getBoolean("tests.verbose");
|
||||
|
||||
/** The Lucene {@link Version} used by the example code. */
|
||||
public static final Version EXAMPLE_VER = Version.LUCENE_40;
|
||||
|
||||
/**
|
||||
* Logs the String representation of <code>msg</code> to the console,
|
||||
* if {@link #VERBOSE} is true. Otherwise, does nothing.
|
||||
* @see #VERBOSE
|
||||
*/
|
||||
public static void log(Object msg) {
|
||||
if (VERBOSE) {
|
||||
System.out.println(msg.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.util.Version;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
|
@ -22,31 +20,13 @@ import org.apache.lucene.facet.search.FacetResult;
|
|||
*/
|
||||
|
||||
/**
|
||||
* Result of running an example program.
|
||||
* This is a general object for allowing to write a test
|
||||
* that runs an example and verifies its results.
|
||||
* Hold various constants used by facet examples.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class ExampleResult {
|
||||
public interface FacetExamples {
|
||||
|
||||
/** Sole constructor. */
|
||||
public ExampleResult() {}
|
||||
|
||||
private List<FacetResult> facetResults;
|
||||
|
||||
/**
|
||||
* Returns the facet results
|
||||
*/
|
||||
public List<FacetResult> getFacetResults() {
|
||||
return facetResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the facet results
|
||||
*/
|
||||
public void setFacetResults(List<FacetResult> facetResults) {
|
||||
this.facetResults = facetResults;
|
||||
}
|
||||
/** The Lucene {@link Version} used by the example code. */
|
||||
public static final Version EXAMPLES_VER = Version.LUCENE_50;
|
||||
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.facet.index.FacetFields;
|
||||
import org.apache.lucene.facet.params.CategoryListParams;
|
||||
import org.apache.lucene.facet.params.FacetIndexingParams;
|
||||
import org.apache.lucene.facet.params.FacetSearchParams;
|
||||
import org.apache.lucene.facet.params.PerDimensionIndexingParams;
|
||||
import org.apache.lucene.facet.search.CountFacetRequest;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.search.FacetsCollector;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** Demonstrates indexing categories into different category lists. */
|
||||
public class MultiCategoryListsFacetsExample {
|
||||
|
||||
private final FacetIndexingParams indexingParams;
|
||||
private final Directory indexDir = new RAMDirectory();
|
||||
private final Directory taxoDir = new RAMDirectory();
|
||||
|
||||
/** Creates a new instance and populates the catetory list params mapping. */
|
||||
public MultiCategoryListsFacetsExample() {
|
||||
// index all Author facets in one category list and all Publish Date in another.
|
||||
Map<CategoryPath,CategoryListParams> categoryListParams = new HashMap<CategoryPath,CategoryListParams>();
|
||||
categoryListParams.put(new CategoryPath("Author"), new CategoryListParams("author"));
|
||||
categoryListParams.put(new CategoryPath("Publish Date"), new CategoryListParams("pubdate"));
|
||||
indexingParams = new PerDimensionIndexingParams(categoryListParams);
|
||||
}
|
||||
|
||||
private void add(IndexWriter indexWriter, FacetFields facetFields, String ... categoryPaths) throws IOException {
|
||||
Document doc = new Document();
|
||||
|
||||
List<CategoryPath> paths = new ArrayList<CategoryPath>();
|
||||
for (String categoryPath : categoryPaths) {
|
||||
paths.add(new CategoryPath(categoryPath, '/'));
|
||||
}
|
||||
facetFields.addFields(doc, paths);
|
||||
indexWriter.addDocument(doc);
|
||||
}
|
||||
|
||||
/** Build the example index. */
|
||||
private void index() throws IOException {
|
||||
IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER,
|
||||
new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER)));
|
||||
|
||||
// Writes facet ords to a separate directory from the main index
|
||||
DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir, IndexWriterConfig.OpenMode.CREATE);
|
||||
|
||||
// Reused across documents, to add the necessary facet fields
|
||||
FacetFields facetFields = new FacetFields(taxoWriter, indexingParams);
|
||||
|
||||
add(indexWriter, facetFields, "Author/Bob", "Publish Date/2010/10/15");
|
||||
add(indexWriter, facetFields, "Author/Lisa", "Publish Date/2010/10/20");
|
||||
add(indexWriter, facetFields, "Author/Lisa", "Publish Date/2012/1/1");
|
||||
add(indexWriter, facetFields, "Author/Susan", "Publish Date/2012/1/7");
|
||||
add(indexWriter, facetFields, "Author/Frank", "Publish Date/1999/5/5");
|
||||
|
||||
indexWriter.close();
|
||||
taxoWriter.close();
|
||||
}
|
||||
|
||||
/** User runs a query and counts facets. */
|
||||
private List<FacetResult> search() throws IOException {
|
||||
DirectoryReader indexReader = DirectoryReader.open(indexDir);
|
||||
IndexSearcher searcher = new IndexSearcher(indexReader);
|
||||
TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
|
||||
|
||||
// Count both "Publish Date" and "Author" dimensions
|
||||
FacetSearchParams fsp = new FacetSearchParams(indexingParams,
|
||||
new CountFacetRequest(new CategoryPath("Publish Date"), 10),
|
||||
new CountFacetRequest(new CategoryPath("Author"), 10));
|
||||
|
||||
// Aggregatses the facet counts
|
||||
FacetsCollector fc = FacetsCollector.create(fsp, searcher.getIndexReader(), taxoReader);
|
||||
|
||||
// MatchAllDocsQuery is for "browsing" (counts facets
|
||||
// for all non-deleted docs in the index); normally
|
||||
// you'd use a "normal" query, and use MultiCollector to
|
||||
// wrap collecting the "normal" hits and also facets:
|
||||
searcher.search(new MatchAllDocsQuery(), fc);
|
||||
|
||||
// Retrieve results
|
||||
List<FacetResult> facetResults = fc.getFacetResults();
|
||||
|
||||
indexReader.close();
|
||||
taxoReader.close();
|
||||
|
||||
return facetResults;
|
||||
}
|
||||
|
||||
/** Runs the search example. */
|
||||
public List<FacetResult> runSearch() throws IOException {
|
||||
index();
|
||||
return search();
|
||||
}
|
||||
|
||||
/** Runs the search example and prints the results. */
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Facet counting over multiple category lists example:");
|
||||
System.out.println("-----------------------");
|
||||
List<FacetResult> results = new MultiCategoryListsFacetsExample().runSearch();
|
||||
for (FacetResult res : results) {
|
||||
System.out.println(res);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.facet.index.FacetFields;
|
||||
import org.apache.lucene.facet.params.FacetSearchParams;
|
||||
import org.apache.lucene.facet.search.CountFacetRequest;
|
||||
import org.apache.lucene.facet.search.DrillDownQuery;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.search.FacetsCollector;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** Shows simple usage of faceted indexing and search. */
|
||||
public class SimpleFacetsExample {
|
||||
|
||||
private final Directory indexDir = new RAMDirectory();
|
||||
private final Directory taxoDir = new RAMDirectory();
|
||||
|
||||
/** Empty constructor */
|
||||
public SimpleFacetsExample() {}
|
||||
|
||||
private void add(IndexWriter indexWriter, FacetFields facetFields, String ... categoryPaths) throws IOException {
|
||||
Document doc = new Document();
|
||||
|
||||
List<CategoryPath> paths = new ArrayList<CategoryPath>();
|
||||
for (String categoryPath : categoryPaths) {
|
||||
paths.add(new CategoryPath(categoryPath, '/'));
|
||||
}
|
||||
facetFields.addFields(doc, paths);
|
||||
indexWriter.addDocument(doc);
|
||||
}
|
||||
|
||||
/** Build the example index. */
|
||||
private void index() throws IOException {
|
||||
IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(FacetExamples.EXAMPLES_VER,
|
||||
new WhitespaceAnalyzer(FacetExamples.EXAMPLES_VER)));
|
||||
|
||||
// Writes facet ords to a separate directory from the main index
|
||||
DirectoryTaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir, IndexWriterConfig.OpenMode.CREATE);
|
||||
|
||||
// Reused across documents, to add the necessary facet fields
|
||||
FacetFields facetFields = new FacetFields(taxoWriter);
|
||||
|
||||
add(indexWriter, facetFields, "Author/Bob", "Publish Date/2010/10/15");
|
||||
add(indexWriter, facetFields, "Author/Lisa", "Publish Date/2010/10/20");
|
||||
add(indexWriter, facetFields, "Author/Lisa", "Publish Date/2012/1/1");
|
||||
add(indexWriter, facetFields, "Author/Susan", "Publish Date/2012/1/7");
|
||||
add(indexWriter, facetFields, "Author/Frank", "Publish Date/1999/5/5");
|
||||
|
||||
indexWriter.close();
|
||||
taxoWriter.close();
|
||||
}
|
||||
|
||||
/** User runs a query and counts facets. */
|
||||
private List<FacetResult> search() throws IOException {
|
||||
DirectoryReader indexReader = DirectoryReader.open(indexDir);
|
||||
IndexSearcher searcher = new IndexSearcher(indexReader);
|
||||
TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
|
||||
|
||||
// Count both "Publish Date" and "Author" dimensions
|
||||
FacetSearchParams fsp = new FacetSearchParams(
|
||||
new CountFacetRequest(new CategoryPath("Publish Date"), 10),
|
||||
new CountFacetRequest(new CategoryPath("Author"), 10));
|
||||
|
||||
// Aggregatses the facet counts
|
||||
FacetsCollector fc = FacetsCollector.create(fsp, searcher.getIndexReader(), taxoReader);
|
||||
|
||||
// MatchAllDocsQuery is for "browsing" (counts facets
|
||||
// for all non-deleted docs in the index); normally
|
||||
// you'd use a "normal" query, and use MultiCollector to
|
||||
// wrap collecting the "normal" hits and also facets:
|
||||
searcher.search(new MatchAllDocsQuery(), fc);
|
||||
|
||||
// Retrieve results
|
||||
List<FacetResult> facetResults = fc.getFacetResults();
|
||||
|
||||
indexReader.close();
|
||||
taxoReader.close();
|
||||
|
||||
return facetResults;
|
||||
}
|
||||
|
||||
/** User drills down on 'Publish date/2010'. */
|
||||
private List<FacetResult> drillDown() throws IOException {
|
||||
DirectoryReader indexReader = DirectoryReader.open(indexDir);
|
||||
IndexSearcher searcher = new IndexSearcher(indexReader);
|
||||
TaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir);
|
||||
|
||||
// Now user drills down on Publish Date/2010:
|
||||
FacetSearchParams fsp = new FacetSearchParams(new CountFacetRequest(new CategoryPath("Author"), 10));
|
||||
DrillDownQuery q = new DrillDownQuery(fsp.indexingParams, new MatchAllDocsQuery());
|
||||
q.add(new CategoryPath("Publish Date/2010", '/'));
|
||||
FacetsCollector fc = FacetsCollector.create(fsp, searcher.getIndexReader(), taxoReader);
|
||||
searcher.search(q, fc);
|
||||
|
||||
// Retrieve results
|
||||
List<FacetResult> facetResults = fc.getFacetResults();
|
||||
|
||||
indexReader.close();
|
||||
taxoReader.close();
|
||||
|
||||
return facetResults;
|
||||
}
|
||||
|
||||
/** Runs the search example. */
|
||||
public List<FacetResult> runSearch() throws IOException {
|
||||
index();
|
||||
return search();
|
||||
}
|
||||
|
||||
/** Runs the drill-down example. */
|
||||
public List<FacetResult> runDrillDown() throws IOException {
|
||||
index();
|
||||
return drillDown();
|
||||
}
|
||||
|
||||
/** Runs the search and drill-down examples and prints the results. */
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Facet counting example:");
|
||||
System.out.println("-----------------------");
|
||||
List<FacetResult> results = new SimpleFacetsExample().runSearch();
|
||||
for (FacetResult res : results) {
|
||||
System.out.println(res);
|
||||
}
|
||||
|
||||
System.out.println("\n");
|
||||
System.out.println("Facet drill-down example (Publish Date/2010):");
|
||||
System.out.println("---------------------------------------------");
|
||||
results = new SimpleFacetsExample().runDrillDown();
|
||||
for (FacetResult res : results) {
|
||||
System.out.println(res);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.adaptive;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
import org.apache.lucene.demo.facet.ExampleResult;
|
||||
import org.apache.lucene.demo.facet.ExampleUtils;
|
||||
import org.apache.lucene.demo.facet.simple.SimpleIndexer;
|
||||
import org.apache.lucene.demo.facet.simple.SimpleSearcher;
|
||||
import org.apache.lucene.facet.search.AdaptiveFacetsAccumulator;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Driver for the adaptive sample, using the {@link AdaptiveFacetsAccumulator}.
|
||||
* Indexing is the same as in {@link SimpleSearcher}
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class AdaptiveMain {
|
||||
|
||||
/** Sole constructor */
|
||||
public AdaptiveMain() {}
|
||||
|
||||
/**
|
||||
* Driver for the adaptive sample.
|
||||
* @throws Exception on error (no detailed exception handling here for sample simplicity
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
new AdaptiveMain().runSample();
|
||||
ExampleUtils.log("DONE");
|
||||
}
|
||||
|
||||
/** Runs the adaptive sample and returns the facet results */
|
||||
public ExampleResult runSample() throws Exception {
|
||||
|
||||
// create Directories for the search index and for the taxonomy index
|
||||
Directory indexDir = new RAMDirectory();
|
||||
Directory taxoDir = new RAMDirectory();
|
||||
|
||||
// index the sample documents
|
||||
ExampleUtils.log("index the adaptive sample documents...");
|
||||
SimpleIndexer.index(indexDir, taxoDir);
|
||||
|
||||
ExampleUtils.log("search the adaptive sample documents...");
|
||||
List<FacetResult> facetRes = AdaptiveSearcher.searchWithFacets(indexDir, taxoDir);
|
||||
|
||||
ExampleResult res = new ExampleResult();
|
||||
res.setFacetResults(facetRes);
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.adaptive;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.demo.facet.ExampleUtils;
|
||||
import org.apache.lucene.demo.facet.simple.SimpleUtils;
|
||||
import org.apache.lucene.facet.params.FacetSearchParams;
|
||||
import org.apache.lucene.facet.search.AdaptiveFacetsAccumulator;
|
||||
import org.apache.lucene.facet.search.CountFacetRequest;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.search.FacetsCollector;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MultiCollector;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.search.TopScoreDocCollector;
|
||||
import org.apache.lucene.store.Directory;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Search with facets through the {@link AdaptiveFacetsAccumulator}
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class AdaptiveSearcher {
|
||||
|
||||
/** No instance */
|
||||
private AdaptiveSearcher() {}
|
||||
|
||||
/**
|
||||
* Search with facets through the {@link AdaptiveFacetsAccumulator}
|
||||
* @param indexDir Directory of the search index.
|
||||
* @param taxoDir Directory of the taxonomy index.
|
||||
* @throws Exception on error (no detailed exception handling here for sample simplicity
|
||||
* @return facet results
|
||||
*/
|
||||
public static List<FacetResult> searchWithFacets(Directory indexDir, Directory taxoDir) throws Exception {
|
||||
// prepare index reader and taxonomy.
|
||||
TaxonomyReader taxo = new DirectoryTaxonomyReader(taxoDir);
|
||||
IndexReader indexReader = DirectoryReader.open(indexDir);
|
||||
|
||||
// prepare searcher to search against
|
||||
IndexSearcher searcher = new IndexSearcher(indexReader);
|
||||
|
||||
// faceted search is working in 2 steps:
|
||||
// 1. collect matching documents
|
||||
// 2. aggregate facets for collected documents and
|
||||
// generate the requested faceted results from the aggregated facets
|
||||
|
||||
// step 1: collect matching documents into a collector
|
||||
Query q = new TermQuery(new Term(SimpleUtils.TEXT,"white"));
|
||||
ExampleUtils.log("Query: "+q);
|
||||
|
||||
// regular collector for scoring matched documents
|
||||
TopScoreDocCollector topDocsCollector = TopScoreDocCollector.create(10, true);
|
||||
|
||||
// Faceted search parameters indicate which facets are we interested in
|
||||
FacetSearchParams fsp = new FacetSearchParams(new CountFacetRequest(new CategoryPath("root", "a"), 10));
|
||||
AdaptiveFacetsAccumulator accumulator = new AdaptiveFacetsAccumulator(fsp, indexReader, taxo);
|
||||
FacetsCollector fc = FacetsCollector.create(accumulator);
|
||||
|
||||
// search, into both collectors. note: in case only facets accumulation
|
||||
// is required, the topDocCollector part can be totally discarded
|
||||
searcher.search(q, MultiCollector.wrap(topDocsCollector, fc));
|
||||
|
||||
// Obtain facets results and print them
|
||||
List<FacetResult> res = fc.getFacetResults();
|
||||
|
||||
int i = 0;
|
||||
for (FacetResult facetResult : res) {
|
||||
ExampleUtils.log("Res "+(i++)+": "+facetResult);
|
||||
}
|
||||
|
||||
// we're done, close the index reader and the taxonomy.
|
||||
indexReader.close();
|
||||
taxo.close();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<html><head></head>
|
||||
<body>
|
||||
Facets example code for using AdaptiveFacetsAccumulator.
|
||||
</body>
|
||||
</html>
|
|
@ -1,122 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.association;
|
||||
|
||||
import org.apache.lucene.demo.facet.ExampleUtils;
|
||||
import org.apache.lucene.demo.facet.simple.SimpleUtils;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.TextField;
|
||||
import org.apache.lucene.facet.associations.AssociationsFacetFields;
|
||||
import org.apache.lucene.facet.associations.CategoryAssociation;
|
||||
import org.apache.lucene.facet.associations.CategoryAssociationsContainer;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.facet.taxonomy.TaxonomyWriter;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
|
||||
import org.apache.lucene.store.Directory;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sample indexer creates an index, and adds to it sample documents with
|
||||
* categories, which can be simple or contain associations.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class CategoryAssociationsIndexer {
|
||||
|
||||
/** No instance. */
|
||||
private CategoryAssociationsIndexer() {}
|
||||
|
||||
/**
|
||||
* Create an index, and adds to it sample documents and categories.
|
||||
*
|
||||
* @param indexDir
|
||||
* Directory in which the index should be created.
|
||||
* @param taxoDir
|
||||
* Directory in which the taxonomy index should be created.
|
||||
* @throws Exception
|
||||
* on error (no detailed exception handling here for sample
|
||||
* simplicity
|
||||
*/
|
||||
public static void index(Directory indexDir, Directory taxoDir) throws Exception {
|
||||
|
||||
// create and open an index writer
|
||||
IndexWriter iw = new IndexWriter(indexDir, new IndexWriterConfig(ExampleUtils.EXAMPLE_VER, SimpleUtils.analyzer));
|
||||
|
||||
// create and open a taxonomy writer
|
||||
TaxonomyWriter taxo = new DirectoryTaxonomyWriter(taxoDir, OpenMode.CREATE);
|
||||
|
||||
AssociationsFacetFields assocFacetFields = new AssociationsFacetFields(taxo);
|
||||
|
||||
// loop over sample documents
|
||||
int nDocsAdded = 0;
|
||||
int nFacetsAdded = 0;
|
||||
for (int docNum = 0; docNum < SimpleUtils.docTexts.length; docNum++) {
|
||||
ExampleUtils.log(" ++++ DOC ID: " + docNum);
|
||||
// obtain the sample categories for current document
|
||||
CategoryAssociationsContainer associations = new CategoryAssociationsContainer();
|
||||
for (CategoryPath path : SimpleUtils.categories[docNum]) {
|
||||
associations.setAssociation(path, null);
|
||||
ExampleUtils.log("\t ++++ PATH: " + path);
|
||||
++nFacetsAdded;
|
||||
}
|
||||
// and also those with associations
|
||||
CategoryPath[] associationsPaths = CategoryAssociationsUtils.categories[docNum];
|
||||
CategoryAssociation[] associationsValues = CategoryAssociationsUtils.associations[docNum];
|
||||
for (int i = 0; i < associationsPaths.length; i++) {
|
||||
associations.setAssociation(associationsPaths[i], associationsValues[i]);
|
||||
ExampleUtils.log("\t $$$$ Association: (" + associationsPaths[i] + "," + associationsValues[i] + ")");
|
||||
++nFacetsAdded;
|
||||
}
|
||||
|
||||
// create a plain Lucene document and add some regular Lucene fields
|
||||
// to it
|
||||
Document doc = new Document();
|
||||
doc.add(new TextField(SimpleUtils.TITLE, SimpleUtils.docTitles[docNum], Field.Store.YES));
|
||||
doc.add(new TextField(SimpleUtils.TEXT, SimpleUtils.docTexts[docNum], Field.Store.NO));
|
||||
|
||||
// invoke the category document builder for adding categories to the
|
||||
// document and, as required, to the taxonomy index
|
||||
assocFacetFields.addFields(doc, associations);
|
||||
|
||||
// finally add the document to the index
|
||||
iw.addDocument(doc);
|
||||
|
||||
nDocsAdded++;
|
||||
}
|
||||
|
||||
// commit changes.
|
||||
// we commit changes to the taxonomy index prior to committing them to
|
||||
// the search index.
|
||||
// this is important, so that all facets referred to by documents in the
|
||||
// search index
|
||||
// will indeed exist in the taxonomy index.
|
||||
taxo.commit();
|
||||
iw.commit();
|
||||
|
||||
// close the taxonomy index and the index - all modifications are
|
||||
// now safely in the provided directories: indexDir and taxoDir.
|
||||
taxo.close();
|
||||
iw.close();
|
||||
|
||||
ExampleUtils.log("Indexed " + nDocsAdded + " documents with overall " + nFacetsAdded + " facets.");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.association;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
import org.apache.lucene.demo.facet.ExampleResult;
|
||||
import org.apache.lucene.demo.facet.ExampleUtils;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Driver for the simple sample.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class CategoryAssociationsMain {
|
||||
|
||||
/** Sole constructor. */
|
||||
public CategoryAssociationsMain() {}
|
||||
|
||||
/**
|
||||
* Driver for the simple sample.
|
||||
* @throws Exception on error (no detailed exception handling here for sample simplicity
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
new CategoryAssociationsMain().runSumIntAssociationSample();
|
||||
new CategoryAssociationsMain().runSumFloatAssociationSample();
|
||||
ExampleUtils.log("DONE");
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the example demonstrating sum of int-association.
|
||||
*/
|
||||
public ExampleResult runSumIntAssociationSample() throws Exception {
|
||||
|
||||
// create Directories for the search index and for the taxonomy index
|
||||
Directory indexDir = new RAMDirectory();//FSDirectory.open(new File("/tmp/111"));
|
||||
Directory taxoDir = new RAMDirectory();
|
||||
|
||||
// index the sample documents
|
||||
ExampleUtils.log("index the sample documents...");
|
||||
CategoryAssociationsIndexer.index(indexDir, taxoDir);
|
||||
|
||||
ExampleUtils.log("search the sample documents...");
|
||||
List<FacetResult> facetRes = CategoryAssociationsSearcher.searchSumIntAssociation(indexDir, taxoDir);
|
||||
|
||||
ExampleResult res = new ExampleResult();
|
||||
res.setFacetResults(facetRes);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the example demonstrating sum of float-association.
|
||||
*/
|
||||
public ExampleResult runSumFloatAssociationSample() throws Exception {
|
||||
|
||||
// create Directories for the search index and for the taxonomy index
|
||||
Directory indexDir = new RAMDirectory();//FSDirectory.open(new File("/tmp/111"));
|
||||
Directory taxoDir = new RAMDirectory();
|
||||
|
||||
// index the sample documents
|
||||
ExampleUtils.log("index the sample documents...");
|
||||
CategoryAssociationsIndexer.index(indexDir, taxoDir);
|
||||
|
||||
ExampleUtils.log("search the sample documents...");
|
||||
List<FacetResult> facetRes = CategoryAssociationsSearcher.searchSumFloatAssociation(indexDir, taxoDir);
|
||||
|
||||
ExampleResult res = new ExampleResult();
|
||||
res.setFacetResults(facetRes);
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.association;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.store.Directory;
|
||||
|
||||
import org.apache.lucene.demo.facet.simple.SimpleSearcher;
|
||||
import org.apache.lucene.facet.associations.AssociationFloatSumFacetRequest;
|
||||
import org.apache.lucene.facet.associations.AssociationIntSumFacetRequest;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* AssociationSearcher searches index with facets, evaluating the facets with
|
||||
* their associated $int value
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class CategoryAssociationsSearcher {
|
||||
|
||||
/** No instantiation */
|
||||
private CategoryAssociationsSearcher() {}
|
||||
|
||||
/** Search an index with a sum of int-association. */
|
||||
public static List<FacetResult> searchSumIntAssociation(Directory indexDir, Directory taxoDir) throws Exception {
|
||||
// prepare index reader
|
||||
IndexReader indexReader = DirectoryReader.open(indexDir);
|
||||
TaxonomyReader taxo = new DirectoryTaxonomyReader(taxoDir);
|
||||
|
||||
AssociationIntSumFacetRequest facetRequest = new AssociationIntSumFacetRequest(new CategoryPath("tags"), 10);
|
||||
List<FacetResult> res = SimpleSearcher.searchWithRequest(indexReader, taxo, null, facetRequest);
|
||||
|
||||
// close readers
|
||||
taxo.close();
|
||||
indexReader.close();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Search an index with a sum of float-association. */
|
||||
public static List<FacetResult> searchSumFloatAssociation(Directory indexDir, Directory taxoDir) throws Exception {
|
||||
// prepare index reader
|
||||
IndexReader indexReader = DirectoryReader.open(indexDir);
|
||||
TaxonomyReader taxo = new DirectoryTaxonomyReader(taxoDir);
|
||||
|
||||
AssociationFloatSumFacetRequest facetRequest = new AssociationFloatSumFacetRequest(new CategoryPath("genre"), 10);
|
||||
|
||||
List<FacetResult> res = SimpleSearcher.searchWithRequest(indexReader, taxo, null, facetRequest);
|
||||
|
||||
// close readers
|
||||
taxo.close();
|
||||
indexReader.close();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.association;
|
||||
|
||||
import org.apache.lucene.facet.associations.CategoryAssociation;
|
||||
import org.apache.lucene.facet.associations.CategoryFloatAssociation;
|
||||
import org.apache.lucene.facet.associations.CategoryIntAssociation;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Categories for the facet examples
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class CategoryAssociationsUtils {
|
||||
|
||||
/** No instance */
|
||||
private CategoryAssociationsUtils() {}
|
||||
|
||||
/**
|
||||
* Categories: categories[D][N] == category-path with association no. N for
|
||||
* document no. D.
|
||||
*/
|
||||
public static CategoryPath[][] categories = {
|
||||
// Doc #1
|
||||
{ new CategoryPath("tags", "lucene") ,
|
||||
new CategoryPath("genre", "computing")
|
||||
},
|
||||
|
||||
// Doc #2
|
||||
{ new CategoryPath("tags", "lucene"),
|
||||
new CategoryPath("tags", "solr"),
|
||||
new CategoryPath("genre", "computing"),
|
||||
new CategoryPath("genre", "software")
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Associations (occurrences/confidence levels) for {@link #categories}
|
||||
*/
|
||||
public static CategoryAssociation[][] associations = {
|
||||
// Doc #1 associations
|
||||
{
|
||||
/* 3 occurrences for tag 'lucene' */
|
||||
new CategoryIntAssociation(3),
|
||||
/* 87% confidence level of genre 'computing' */
|
||||
new CategoryFloatAssociation(0.87f)
|
||||
},
|
||||
|
||||
// Doc #2 associations
|
||||
{
|
||||
/* 1 occurrence for tag 'lucene' */
|
||||
new CategoryIntAssociation(1),
|
||||
/* 2 occurrences for tag 'solr' */
|
||||
new CategoryIntAssociation(2),
|
||||
/* 75% confidence level of genre 'computing' */
|
||||
new CategoryFloatAssociation(0.75f),
|
||||
/* 34% confidence level of genre 'software' */
|
||||
new CategoryFloatAssociation(0.34f),
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<html><head></head>
|
||||
<body>
|
||||
Facets example code for using associations.
|
||||
</body>
|
||||
</html>
|
|
@ -1,210 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.multiCL;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.lucene.demo.facet.ExampleUtils;
|
||||
import org.apache.lucene.demo.facet.simple.SimpleUtils;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.TextField;
|
||||
import org.apache.lucene.facet.index.FacetFields;
|
||||
import org.apache.lucene.facet.params.CategoryListParams;
|
||||
import org.apache.lucene.facet.params.FacetIndexingParams;
|
||||
import org.apache.lucene.facet.params.PerDimensionIndexingParams;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sample indexer creates an index, and adds to it sample documents and facets
|
||||
* with multiple CategoryLists specified for different facets, so there are different
|
||||
* category lists for different facets.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class MultiCLIndexer {
|
||||
|
||||
/** No instance */
|
||||
private MultiCLIndexer() {}
|
||||
|
||||
/** Number of documents to index */
|
||||
public static int NUM_DOCS = 100;
|
||||
/** Number of facets to add per document */
|
||||
public static int NUM_FACETS_PER_DOC = 10;
|
||||
/** Number of tokens in title */
|
||||
public static int TITLE_LENGTH = 5;
|
||||
/** Number of tokens in text */
|
||||
public static int TEXT_LENGTH = 100;
|
||||
|
||||
// Lorum ipsum to use as content - this will be tokenized and used for document
|
||||
// titles/text.
|
||||
static String words = "Sed ut perspiciatis unde omnis iste natus error sit "
|
||||
+ "voluptatem accusantium doloremque laudantium totam rem aperiam "
|
||||
+ "eaque ipsa quae ab illo inventore veritatis et quasi architecto "
|
||||
+ "beatae vitae dicta sunt explicabo Nemo enim ipsam voluptatem "
|
||||
+ "quia voluptas sit aspernatur aut odit aut fugit sed quia consequuntur "
|
||||
+ "magni dolores eos qui ratione voluptatem sequi nesciunt Neque porro "
|
||||
+ "quisquam est qui dolorem ipsum quia dolor sit amet consectetur adipisci velit "
|
||||
+ "sed quia non numquam eius modi tempora incidunt ut labore et dolore "
|
||||
+ "magnam aliquam quaerat voluptatem Ut enim ad minima veniam "
|
||||
+ "quis nostrum exercitationem ullam corporis suscipit laboriosam "
|
||||
+ "nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure"
|
||||
+ "reprehenderit qui in ea voluptate velit esse quam nihil molestiae "
|
||||
+ "consequatur vel illum qui dolorem eum fugiat quo voluptas nulla pariatur";
|
||||
/** PerDimensionIndexingParams for multiple category lists */
|
||||
public static final PerDimensionIndexingParams MULTI_IPARAMS;
|
||||
|
||||
// Initialize PerDimensionIndexingParams
|
||||
static {
|
||||
Map<CategoryPath, CategoryListParams> paramsMap = new HashMap<CategoryPath,CategoryListParams>();
|
||||
paramsMap.put(new CategoryPath("0"), new CategoryListParams("$Digits$Zero"));
|
||||
paramsMap.put(new CategoryPath("1"), new CategoryListParams("$Digits$One"));
|
||||
paramsMap.put(new CategoryPath("2"), new CategoryListParams("$Digits$Two"));
|
||||
paramsMap.put(new CategoryPath("3"), new CategoryListParams("$Digits$Three"));
|
||||
paramsMap.put(new CategoryPath("4"), new CategoryListParams("$Digits$Four"));
|
||||
paramsMap.put(new CategoryPath("5"), new CategoryListParams("$Digits$Five"));
|
||||
MULTI_IPARAMS = new PerDimensionIndexingParams(paramsMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an index, and adds to it sample documents and facets.
|
||||
*
|
||||
* @param indexDir
|
||||
* Directory in which the index should be created.
|
||||
* @param taxoDir
|
||||
* Directory in which the taxonomy index should be created.
|
||||
* @throws Exception
|
||||
* on error (no detailed exception handling here for sample
|
||||
* simplicity
|
||||
*/
|
||||
public static void index(Directory indexDir, Directory taxoDir) throws Exception {
|
||||
|
||||
Random random = new Random(2003);
|
||||
|
||||
String[] docTitles = new String[NUM_DOCS];
|
||||
String[] docTexts = new String[NUM_DOCS];
|
||||
CategoryPath[][] cPaths = new CategoryPath[NUM_DOCS][NUM_FACETS_PER_DOC];
|
||||
|
||||
String[] tokens = words.split(" ");
|
||||
for (int docNum = 0; docNum < NUM_DOCS; docNum++) {
|
||||
String title = "";
|
||||
String text = "";
|
||||
for (int j = 0; j < TITLE_LENGTH; j++) {
|
||||
title = title + tokens[random.nextInt(tokens.length)] + " ";
|
||||
}
|
||||
docTitles[docNum] = title;
|
||||
|
||||
for (int j = 0; j < TEXT_LENGTH; j++) {
|
||||
text = text + tokens[random.nextInt(tokens.length)] + " ";
|
||||
}
|
||||
docTexts[docNum] = text;
|
||||
|
||||
for (int facetNum = 0; facetNum < NUM_FACETS_PER_DOC; facetNum++) {
|
||||
cPaths[docNum][facetNum] = new CategoryPath(Integer
|
||||
.toString(random.nextInt(7)), Integer.toString(random.nextInt(10)));
|
||||
}
|
||||
}
|
||||
index(indexDir, taxoDir, MULTI_IPARAMS, docTitles, docTexts, cPaths);
|
||||
}
|
||||
|
||||
/**
|
||||
* More advanced method for specifying custom indexing params, doc texts,
|
||||
* doc titles and category paths.
|
||||
*/
|
||||
public static void index(Directory indexDir, Directory taxoDir,
|
||||
FacetIndexingParams iParams, String[] docTitles,
|
||||
String[] docTexts, CategoryPath[][] cPaths) throws Exception {
|
||||
// create and open an index writer
|
||||
IndexWriter iw = new IndexWriter(indexDir, new IndexWriterConfig(
|
||||
ExampleUtils.EXAMPLE_VER, SimpleUtils.analyzer).setOpenMode(OpenMode.CREATE));
|
||||
// create and open a taxonomy writer
|
||||
DirectoryTaxonomyWriter taxo = new DirectoryTaxonomyWriter(taxoDir, OpenMode.CREATE);
|
||||
index(iw, taxo, iParams, docTitles, docTexts, cPaths);
|
||||
}
|
||||
|
||||
/**
|
||||
* More advanced method for specifying custom indexing params, doc texts,
|
||||
* doc titles and category paths.
|
||||
* <p>
|
||||
* Create an index, and adds to it sample documents and facets.
|
||||
* @throws Exception
|
||||
* on error (no detailed exception handling here for sample
|
||||
* simplicity
|
||||
*/
|
||||
public static void index(IndexWriter iw, DirectoryTaxonomyWriter taxo,
|
||||
FacetIndexingParams iParams, String[] docTitles,
|
||||
String[] docTexts, CategoryPath[][] cPaths) throws Exception {
|
||||
|
||||
// loop over sample documents
|
||||
int nDocsAdded = 0;
|
||||
int nFacetsAdded = 0;
|
||||
for (int docNum = 0; docNum < SimpleUtils.docTexts.length; docNum++) {
|
||||
List<CategoryPath> facetList = Arrays.asList(cPaths[docNum]);
|
||||
|
||||
// we do not alter indexing parameters!
|
||||
// FacetFields adds the categories to the document in addFields()
|
||||
FacetFields facetFields = new FacetFields(taxo, iParams);
|
||||
|
||||
// create a plain Lucene document and add some regular Lucene fields
|
||||
// to it
|
||||
Document doc = new Document();
|
||||
doc.add(new TextField(SimpleUtils.TITLE, docTitles[docNum], Field.Store.YES));
|
||||
doc.add(new TextField(SimpleUtils.TEXT, docTexts[docNum], Field.Store.NO));
|
||||
|
||||
// finally add the document to the index
|
||||
facetFields.addFields(doc, facetList);
|
||||
iw.addDocument(doc);
|
||||
|
||||
nDocsAdded++;
|
||||
nFacetsAdded += facetList.size();
|
||||
}
|
||||
|
||||
// commit changes.
|
||||
// we commit changes to the taxonomy index prior to committing them to
|
||||
// the search index.
|
||||
// this is important, so that all facets referred to by documents in the
|
||||
// search index
|
||||
// will indeed exist in the taxonomy index.
|
||||
taxo.commit();
|
||||
iw.commit();
|
||||
|
||||
// close the taxonomy index and the index - all modifications are
|
||||
// now safely in the provided directories: indexDir and taxoDir.
|
||||
taxo.close();
|
||||
iw.close();
|
||||
|
||||
ExampleUtils.log("Indexed " + nDocsAdded + " documents with overall "
|
||||
+ nFacetsAdded + " facets.");
|
||||
}
|
||||
|
||||
/** Driver for the example */
|
||||
public static void main(String[] args) throws Exception {
|
||||
index(new RAMDirectory(), new RAMDirectory());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.multiCL;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
import org.apache.lucene.demo.facet.ExampleResult;
|
||||
import org.apache.lucene.demo.facet.ExampleUtils;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Driver for the multi sample.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class MultiCLMain {
|
||||
|
||||
/** Sole constructor. */
|
||||
public MultiCLMain() {}
|
||||
|
||||
/**
|
||||
* Executes the multi sample.
|
||||
*
|
||||
* @throws Exception
|
||||
* on error (no detailed exception handling here for sample
|
||||
* simplicity
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
new MultiCLMain().runSample();
|
||||
ExampleUtils.log("DONE");
|
||||
}
|
||||
|
||||
/** Runs the multi sample and returns the facet results */
|
||||
public ExampleResult runSample() throws Exception {
|
||||
|
||||
// create Directories for the search index and for the taxonomy index
|
||||
Directory indexDir = new RAMDirectory();
|
||||
Directory taxoDir = new RAMDirectory();
|
||||
|
||||
// index the sample documents
|
||||
ExampleUtils.log("index the sample documents...");
|
||||
MultiCLIndexer.index(indexDir, taxoDir);
|
||||
|
||||
ExampleUtils.log("search the sample documents...");
|
||||
List<FacetResult> facetRes = MultiCLSearcher.searchWithFacets(indexDir,
|
||||
taxoDir, MultiCLIndexer.MULTI_IPARAMS);
|
||||
|
||||
ExampleResult res = new ExampleResult();
|
||||
res.setFacetResults(facetRes);
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.multiCL;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
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.store.Directory;
|
||||
|
||||
import org.apache.lucene.search.MultiCollector;
|
||||
import org.apache.lucene.demo.facet.ExampleUtils;
|
||||
import org.apache.lucene.demo.facet.simple.SimpleUtils;
|
||||
import org.apache.lucene.facet.params.FacetIndexingParams;
|
||||
import org.apache.lucene.facet.params.FacetSearchParams;
|
||||
import org.apache.lucene.facet.search.CountFacetRequest;
|
||||
import org.apache.lucene.facet.search.FacetRequest;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.search.FacetsCollector;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* MultiSearcher searches index with facets over an index with multiple
|
||||
* category lists.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class MultiCLSearcher {
|
||||
|
||||
/** No instance */
|
||||
private MultiCLSearcher() {}
|
||||
|
||||
/**
|
||||
* Search an index with facets.
|
||||
*
|
||||
* @param indexDir
|
||||
* Directory of the search index.
|
||||
* @param taxoDir
|
||||
* Directory of the taxonomy index.
|
||||
* @throws Exception
|
||||
* on error (no detailed exception handling here for sample
|
||||
* simplicity
|
||||
* @return facet results
|
||||
*/
|
||||
public static List<FacetResult> searchWithFacets(Directory indexDir,
|
||||
Directory taxoDir, FacetIndexingParams iParams) throws Exception {
|
||||
|
||||
// prepare index reader and taxonomy.
|
||||
IndexReader indexReader = DirectoryReader.open(indexDir);
|
||||
TaxonomyReader taxo = new DirectoryTaxonomyReader(taxoDir);
|
||||
|
||||
// Get results
|
||||
List<FacetResult> results = searchWithFacets(indexReader, taxo, iParams);
|
||||
|
||||
// we're done, close the index reader and the taxonomy.
|
||||
indexReader.close();
|
||||
taxo.close();
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search an index with facets.
|
||||
*
|
||||
* @param indexReader
|
||||
* Reader over the search index.
|
||||
* @param taxo
|
||||
* 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 taxo, FacetIndexingParams iParams) throws Exception {
|
||||
// prepare searcher to search against
|
||||
IndexSearcher searcher = new IndexSearcher(indexReader);
|
||||
|
||||
// faceted search is working in 2 steps:
|
||||
// 1. collect matching documents
|
||||
// 2. aggregate facets for collected documents and
|
||||
// generate the requested faceted results from the aggregated facets
|
||||
|
||||
// step 1: create a query for finding matching documents for which we
|
||||
// accumulate facets
|
||||
Query q = new TermQuery(new Term(SimpleUtils.TEXT, "Quis"));
|
||||
ExampleUtils.log("Query: " + q);
|
||||
|
||||
TopScoreDocCollector topDocsCollector = TopScoreDocCollector.create(10, true);
|
||||
|
||||
// Faceted search parameters indicate which facets are we interested in
|
||||
List<FacetRequest> facetRequests = new ArrayList<FacetRequest>();
|
||||
facetRequests.add(new CountFacetRequest(new CategoryPath("5"), 10));
|
||||
facetRequests.add(new CountFacetRequest(new CategoryPath("5", "5"), 10));
|
||||
facetRequests.add(new CountFacetRequest(new CategoryPath("6", "2"), 10));
|
||||
FacetSearchParams facetSearchParams = new FacetSearchParams(iParams, facetRequests);
|
||||
|
||||
// Facets collector is the simplest interface for faceted search.
|
||||
// It provides faceted search functions that are sufficient to many
|
||||
// application,
|
||||
// although it is insufficient for tight control on faceted search
|
||||
// behavior - in those
|
||||
// situations other, more low-level interfaces are available, as
|
||||
// demonstrated in other search examples.
|
||||
FacetsCollector facetsCollector = FacetsCollector.create(facetSearchParams, indexReader, taxo);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<html><head></head>
|
||||
<body>
|
||||
Facets example code for using multiple category lists.
|
||||
</body>
|
||||
</html>
|
|
@ -1,101 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.simple;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.demo.facet.ExampleUtils;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.TextField;
|
||||
import org.apache.lucene.facet.index.FacetFields;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.facet.taxonomy.TaxonomyWriter;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
|
||||
import org.apache.lucene.store.Directory;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sample indexer creates an index, and adds to it sample documents and facets.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class SimpleIndexer {
|
||||
|
||||
/** No instance */
|
||||
private SimpleIndexer() {}
|
||||
|
||||
/**
|
||||
* Create an index, and adds to it sample documents and facets.
|
||||
* @param indexDir Directory in which the index should be created.
|
||||
* @param taxoDir Directory in which the taxonomy index should be created.
|
||||
* @throws Exception on error (no detailed exception handling here for sample simplicity
|
||||
*/
|
||||
public static void index (Directory indexDir, Directory taxoDir) throws Exception {
|
||||
|
||||
// create and open an index writer
|
||||
final IndexWriter iw = new IndexWriter(indexDir,
|
||||
new IndexWriterConfig(ExampleUtils.EXAMPLE_VER, SimpleUtils.analyzer));
|
||||
|
||||
// create and open a taxonomy writer
|
||||
final TaxonomyWriter taxo = new DirectoryTaxonomyWriter(taxoDir, OpenMode.CREATE);
|
||||
|
||||
// FacetFields adds the categories to the document in addFields()
|
||||
final FacetFields facetFields = new FacetFields(taxo);
|
||||
|
||||
// loop over sample documents
|
||||
int nDocsAdded = 0;
|
||||
int nFacetsAdded = 0;
|
||||
for (int docNum = 0; docNum < SimpleUtils.docTexts.length; docNum++) {
|
||||
// obtain the sample facets for current document
|
||||
List<CategoryPath> facetList = Arrays.asList(SimpleUtils.categories[docNum]);
|
||||
|
||||
// create a plain Lucene document and add some regular Lucene fields to it
|
||||
Document doc = new Document();
|
||||
doc.add(new TextField(SimpleUtils.TITLE, SimpleUtils.docTitles[docNum], Field.Store.YES));
|
||||
doc.add(new TextField(SimpleUtils.TEXT, SimpleUtils.docTexts[docNum], Field.Store.NO));
|
||||
|
||||
// add the facet fields to the document
|
||||
facetFields.addFields(doc, facetList);
|
||||
|
||||
// finally add the document to the index
|
||||
iw.addDocument(doc);
|
||||
|
||||
nDocsAdded ++;
|
||||
nFacetsAdded += facetList.size();
|
||||
}
|
||||
|
||||
// commit changes.
|
||||
// we commit changes to the taxonomy index prior to committing them to the search index.
|
||||
// this is important, so that all facets referred to by documents in the search index
|
||||
// will indeed exist in the taxonomy index.
|
||||
taxo.commit();
|
||||
iw.commit();
|
||||
|
||||
// close the taxonomy index and the index - all modifications are
|
||||
// now safely in the provided directories: indexDir and taxoDir.
|
||||
taxo.close();
|
||||
iw.close();
|
||||
|
||||
ExampleUtils.log("Indexed "+nDocsAdded+" documents with overall "+nFacetsAdded+" facets.");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.simple;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
import org.apache.lucene.demo.facet.ExampleResult;
|
||||
import org.apache.lucene.demo.facet.ExampleUtils;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
|
||||
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Driver for the simple sample.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class SimpleMain {
|
||||
|
||||
/** Sole constructor */
|
||||
public SimpleMain() {}
|
||||
|
||||
/**
|
||||
* Driver for the simple sample.
|
||||
* @throws Exception on error (no detailed exception handling here for sample simplicity
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
new SimpleMain().runSimple();
|
||||
new SimpleMain().runDrillDown().getFacetResults();
|
||||
ExampleUtils.log("DONE");
|
||||
}
|
||||
|
||||
/** Runs the simple sample and returns the facet results */
|
||||
public ExampleResult runSimple() throws Exception {
|
||||
// create Directories for the search index and for the taxonomy index
|
||||
Directory indexDir = new RAMDirectory();
|
||||
Directory taxoDir = new RAMDirectory();
|
||||
|
||||
// index the sample documents
|
||||
ExampleUtils.log("index the sample documents...");
|
||||
SimpleIndexer.index(indexDir, taxoDir);
|
||||
|
||||
// open readers
|
||||
TaxonomyReader taxo = new DirectoryTaxonomyReader(taxoDir);
|
||||
IndexReader indexReader = DirectoryReader.open(indexDir);
|
||||
|
||||
ExampleUtils.log("search the sample documents...");
|
||||
List<FacetResult> facetRes = SimpleSearcher.searchWithFacets(indexReader, taxo);
|
||||
|
||||
// close readers
|
||||
taxo.close();
|
||||
indexReader.close();
|
||||
|
||||
ExampleResult res = new ExampleResult();
|
||||
res.setFacetResults(facetRes);
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Runs the simple sample and returns drilldown results */
|
||||
public ExampleResult runDrillDown() throws Exception {
|
||||
// create Directories for the search index and for the taxonomy index
|
||||
Directory indexDir = new RAMDirectory();
|
||||
Directory taxoDir = new RAMDirectory();
|
||||
|
||||
// index the sample documents
|
||||
ExampleUtils.log("index the sample documents...");
|
||||
SimpleIndexer.index(indexDir, taxoDir);
|
||||
|
||||
// open readers
|
||||
TaxonomyReader taxo = new DirectoryTaxonomyReader(taxoDir);
|
||||
IndexReader indexReader = DirectoryReader.open(indexDir);
|
||||
|
||||
ExampleUtils.log("search the sample documents...");
|
||||
List<FacetResult> facetRes = SimpleSearcher.searchWithDrillDown(indexReader, taxo);
|
||||
|
||||
// close readers
|
||||
taxo.close();
|
||||
indexReader.close();
|
||||
|
||||
ExampleResult res = new ExampleResult();
|
||||
res.setFacetResults(facetRes);
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,167 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.simple;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.demo.facet.ExampleUtils;
|
||||
import org.apache.lucene.facet.params.FacetIndexingParams;
|
||||
import org.apache.lucene.facet.params.FacetSearchParams;
|
||||
import org.apache.lucene.facet.search.CountFacetRequest;
|
||||
import org.apache.lucene.facet.search.DrillDownQuery;
|
||||
import org.apache.lucene.facet.search.FacetRequest;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.search.FacetResultNode;
|
||||
import org.apache.lucene.facet.search.FacetsCollector;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.MultiCollector;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.search.TopScoreDocCollector;
|
||||
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
/** No instance */
|
||||
private 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 = FacetIndexingParams.ALL_PARENTS;
|
||||
}
|
||||
|
||||
// Faceted search parameters indicate which facets are we interested in
|
||||
FacetSearchParams facetSearchParams = new FacetSearchParams(indexingParams, facetRequests);
|
||||
|
||||
FacetsCollector facetsCollector = FacetsCollector.create(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 {
|
||||
|
||||
final FacetIndexingParams indexingParams = FacetIndexingParams.ALL_PARENTS;
|
||||
|
||||
// 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, indexingParams, 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().subResults.iterator();
|
||||
resIterator.next(); // skip first result
|
||||
CategoryPath categoryOfInterest = resIterator.next().label;
|
||||
|
||||
// drill-down preparation: turn the base query into a drill-down query for the category of interest
|
||||
DrillDownQuery q2 = new DrillDownQuery(indexingParams, baseQuery);
|
||||
q2.add(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, indexingParams, facetRequest);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
package org.apache.lucene.demo.facet.simple;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
|
||||
import org.apache.lucene.demo.facet.ExampleUtils;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Some definitions for the Simple Sample.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class SimpleUtils {
|
||||
|
||||
/** No instance */
|
||||
private SimpleUtils() {}
|
||||
|
||||
/**
|
||||
* Documents text field.
|
||||
*/
|
||||
public static final String TEXT = "text";
|
||||
|
||||
/**
|
||||
* Documents title field.
|
||||
*/
|
||||
public static final String TITLE = "title";
|
||||
|
||||
/**
|
||||
* sample documents text (for the text field).
|
||||
*/
|
||||
public static String[] docTexts = {
|
||||
"the white car is the one I want.",
|
||||
"the white dog does not belong to anyone.",
|
||||
};
|
||||
|
||||
/**
|
||||
* sample documents titles (for the title field).
|
||||
*/
|
||||
public static String[] docTitles = {
|
||||
"white car",
|
||||
"white dog",
|
||||
};
|
||||
|
||||
/**
|
||||
* Categories: categories[D][N] == category-path no. N for document no. D.
|
||||
*/
|
||||
public static CategoryPath[][] categories = {
|
||||
{ new CategoryPath("root","a","f1"), new CategoryPath("root","a","f2") },
|
||||
{ new CategoryPath("root","a","f1"), new CategoryPath("root","a","f3") },
|
||||
};
|
||||
|
||||
/**
|
||||
* Analyzer used in the simple sample.
|
||||
*/
|
||||
public static final Analyzer analyzer = new WhitespaceAnalyzer(ExampleUtils.EXAMPLE_VER);
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<html><head></head>
|
||||
<body>
|
||||
Facets simple example code.
|
||||
</body>
|
||||
</html>
|
|
@ -1,40 +0,0 @@
|
|||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.apache.lucene.demo.facet.ExampleResult;
|
||||
import org.apache.lucene.demo.facet.adaptive.AdaptiveMain;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test that the adaptive example works as expected. This test helps to verify
|
||||
* that examples code is alive!
|
||||
*/
|
||||
public class TestAdaptiveExample extends LuceneTestCase {
|
||||
|
||||
@Test
|
||||
public void testAdaptive () throws Exception {
|
||||
ExampleResult res = new AdaptiveMain().runSample();
|
||||
assertNotNull("Null result!", res);
|
||||
assertNotNull("Null facet result!", res.getFacetResults());
|
||||
assertEquals("Wrong number of results!",1, res.getFacetResults().size());
|
||||
assertEquals("Wrong number of facets!",3, res.getFacetResults().get(0).getNumValidDescendants());
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import org.junit.Test;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.apache.lucene.demo.facet.ExampleResult;
|
||||
import org.apache.lucene.demo.facet.association.CategoryAssociationsMain;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.search.FacetResultNode;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
|
@ -24,28 +24,23 @@ import org.apache.lucene.facet.search.FacetResultNode;
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test that the association example works as expected. This test helps to
|
||||
* verify that examples code is alive!
|
||||
*/
|
||||
public class TestAssociationExample extends LuceneTestCase {
|
||||
public class TestAssociationsFacetsExample extends LuceneTestCase {
|
||||
|
||||
private static final double[] EXPECTED_INT_SUM_RESULTS = { 4, 2};
|
||||
private static final double[] EXPECTED_FLOAT_SUM_RESULTS = { 1.62, 0.34};
|
||||
|
||||
@Test
|
||||
public void testAssociationExamples() throws Exception {
|
||||
assertExampleResult(new CategoryAssociationsMain().runSumIntAssociationSample(), EXPECTED_INT_SUM_RESULTS);
|
||||
assertExampleResult(new CategoryAssociationsMain().runSumFloatAssociationSample(), EXPECTED_FLOAT_SUM_RESULTS);
|
||||
public void testExamples() throws Exception {
|
||||
assertExampleResult(new AssociationsFacetsExample().runSumIntAssociations(), EXPECTED_INT_SUM_RESULTS);
|
||||
assertExampleResult(new AssociationsFacetsExample().runSumFloatAssociations(), EXPECTED_FLOAT_SUM_RESULTS);
|
||||
}
|
||||
|
||||
private void assertExampleResult(ExampleResult res, double[] expectedResults) {
|
||||
private void assertExampleResult(List<FacetResult> res, double[] expectedResults) {
|
||||
assertNotNull("Null result!", res);
|
||||
assertNotNull("Null facet result!", res.getFacetResults());
|
||||
assertEquals("Wrong number of results!", 1, res.getFacetResults().size());
|
||||
assertEquals("Wrong number of facets!", 2, res.getFacetResults().get(0).getNumValidDescendants());
|
||||
assertEquals("Wrong number of results!", 1, res.size());
|
||||
assertEquals("Wrong number of facets!", 2, res.get(0).getNumValidDescendants());
|
||||
|
||||
Iterable<? extends FacetResultNode> it = res.getFacetResults().get(0).getFacetResultNode().subResults;
|
||||
Iterable<? extends FacetResultNode> it = res.get(0).getFacetResultNode().subResults;
|
||||
int i = 0;
|
||||
for (FacetResultNode fResNode : it) {
|
||||
assertEquals("Wrong result for facet "+fResNode.label, expectedResults[i++], fResNode.value, 1E-5);
|
|
@ -1,78 +0,0 @@
|
|||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.apache.lucene.demo.facet.ExampleResult;
|
||||
import org.apache.lucene.demo.facet.multiCL.MultiCLMain;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.search.FacetResultNode;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test that the multi-category list example works as expected. This test helps
|
||||
* to verify that examples code is alive!
|
||||
*/
|
||||
public class TestMultiCLExample extends LuceneTestCase {
|
||||
|
||||
@Test
|
||||
public void testMulti() throws Exception {
|
||||
ExampleResult res = new MultiCLMain().runSample();
|
||||
assertCorrectMultiResults(res);
|
||||
}
|
||||
|
||||
public static void assertCorrectMultiResults(ExampleResult exampleResults) {
|
||||
List<FacetResult> results = exampleResults.getFacetResults();
|
||||
FacetResult result = results.get(0);
|
||||
assertNotNull("Result should not be null", result);
|
||||
FacetResultNode node = result.getFacetResultNode();
|
||||
assertEquals("Invalid label", "5", node.label.toString());
|
||||
assertEquals("Invalid # of subresults", 3, node.subResults.size());
|
||||
|
||||
Iterator<? extends FacetResultNode> subResults = node.subResults.iterator();
|
||||
FacetResultNode sub = subResults.next();
|
||||
assertEquals("Invalid subresult value", 1.0, sub.value, 0.0);
|
||||
assertEquals("Invalid subresult label", "5/2", sub.label.toString());
|
||||
sub = subResults.next();
|
||||
assertEquals("Invalid subresult value", 1.0, sub.value, 0.0);
|
||||
assertEquals("Invalid subresult label", "5/7", sub.label.toString());
|
||||
sub = subResults.next();
|
||||
assertEquals("Invalid subresult value", 1.0, sub.value, 0.0);
|
||||
assertEquals("Invalid subresult label", "5/5", sub.label.toString());
|
||||
|
||||
result = results.get(1);
|
||||
node = result.getFacetResultNode();
|
||||
assertNotNull("Result should not be null", result);
|
||||
assertEquals("Invalid label", "5/5", node.label.toString());
|
||||
assertEquals("Invalid value", 1, node.value, 0.0);
|
||||
assertEquals("Invalid number of subresults", 0, node.subResults.size());
|
||||
|
||||
result = results.get(2);
|
||||
node = result.getFacetResultNode();
|
||||
assertNotNull("Result should not be null", result);
|
||||
assertEquals("Invalid label", "6/2", node.label.toString());
|
||||
assertEquals("Invalid value", 1, node.value, 0.0);
|
||||
assertEquals("Invalid number of subresults", 0, node.subResults.size());
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.facet.collections.ObjectToIntMap;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.search.FacetResultNode;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
public class TestMultiCategoryListsFacetsExample extends LuceneTestCase {
|
||||
|
||||
private static final ObjectToIntMap<CategoryPath> expectedCounts = new ObjectToIntMap<CategoryPath>();
|
||||
static {
|
||||
expectedCounts.put(new CategoryPath("Publish Date", "2012"), 2);
|
||||
expectedCounts.put(new CategoryPath("Publish Date", "2010"), 2);
|
||||
expectedCounts.put(new CategoryPath("Publish Date", "1999"), 1);
|
||||
expectedCounts.put(new CategoryPath("Author", "Lisa"), 2);
|
||||
expectedCounts.put(new CategoryPath("Author", "Frank"), 1);
|
||||
expectedCounts.put(new CategoryPath("Author", "Susan"), 1);
|
||||
expectedCounts.put(new CategoryPath("Author", "Bob"), 1);
|
||||
}
|
||||
|
||||
private void assertExpectedCounts(List<FacetResult> facetResults, ObjectToIntMap<CategoryPath> expCounts) {
|
||||
for (FacetResult res : facetResults) {
|
||||
FacetResultNode root = res.getFacetResultNode();
|
||||
for (FacetResultNode node : root.subResults) {
|
||||
assertEquals("incorrect count for " + node.label, expCounts.get(node.label), (int) node.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExample() throws Exception {
|
||||
List<FacetResult> facetResults = new MultiCategoryListsFacetsExample().runSearch();
|
||||
assertEquals(2, facetResults.size());
|
||||
assertExpectedCounts(facetResults, expectedCounts);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.apache.lucene.demo.facet.ExampleResult;
|
||||
import org.apache.lucene.demo.facet.simple.SimpleMain;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.search.FacetResultNode;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test that the simple example works as expected. This test helps to verify
|
||||
* that examples code is alive!
|
||||
*/
|
||||
public class TestSimpleExample extends LuceneTestCase {
|
||||
|
||||
@Test
|
||||
public void testSimple() throws Exception {
|
||||
ExampleResult res = new SimpleMain().runSimple();
|
||||
assertNotNull("Null result!", res);
|
||||
assertNotNull("Null facet result!", res.getFacetResults());
|
||||
assertEquals("Wrong number of results!",1, res.getFacetResults().size());
|
||||
assertEquals("Wrong number of facets!",3, res.getFacetResults().get(0).getNumValidDescendants());
|
||||
}
|
||||
|
||||
/**
|
||||
* In drill down test we are drilling down to a facet that appears in a single document.
|
||||
* As result, facets that without drill down got count of 2 will now get a count of 1.
|
||||
*/
|
||||
@Test
|
||||
public void testDrillDown() throws Exception {
|
||||
ExampleResult res = new SimpleMain().runDrillDown();
|
||||
assertNotNull("Null result!", res);
|
||||
assertNotNull("Null facet result!", res.getFacetResults());
|
||||
assertEquals("Wrong number of results!",1, res.getFacetResults().size());
|
||||
|
||||
// drill down facet appears in only 1 doc, and that doc has only 2 facets
|
||||
FacetResult facetResult = res.getFacetResults().get(0);
|
||||
assertEquals("Wrong number of facets!",2, facetResult.getNumValidDescendants());
|
||||
|
||||
Iterator<? extends FacetResultNode> resIterator = facetResult.getFacetResultNode().subResults.iterator();
|
||||
assertTrue("Too few results", resIterator.hasNext());
|
||||
assertEquals("wrong count for first result out of 2", 1, (int)resIterator.next().value);
|
||||
assertTrue("Too few results", resIterator.hasNext());
|
||||
assertEquals("wrong count for second result out of 2", 1, (int)resIterator.next().value);
|
||||
assertFalse("Too many results!", resIterator.hasNext());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package org.apache.lucene.demo.facet;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.facet.collections.ObjectToIntMap;
|
||||
import org.apache.lucene.facet.search.FacetResult;
|
||||
import org.apache.lucene.facet.search.FacetResultNode;
|
||||
import org.apache.lucene.facet.taxonomy.CategoryPath;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
public class TestSimpleFacetsExample extends LuceneTestCase {
|
||||
|
||||
private static final ObjectToIntMap<CategoryPath> expectedCounts = new ObjectToIntMap<CategoryPath>();
|
||||
static {
|
||||
expectedCounts.put(new CategoryPath("Publish Date", "2012"), 2);
|
||||
expectedCounts.put(new CategoryPath("Publish Date", "2010"), 2);
|
||||
expectedCounts.put(new CategoryPath("Publish Date", "1999"), 1);
|
||||
expectedCounts.put(new CategoryPath("Author", "Lisa"), 2);
|
||||
expectedCounts.put(new CategoryPath("Author", "Frank"), 1);
|
||||
expectedCounts.put(new CategoryPath("Author", "Susan"), 1);
|
||||
expectedCounts.put(new CategoryPath("Author", "Bob"), 1);
|
||||
}
|
||||
|
||||
private static final ObjectToIntMap<CategoryPath> expectedCountsDrillDown = new ObjectToIntMap<CategoryPath>();
|
||||
static {
|
||||
expectedCountsDrillDown.put(new CategoryPath("Author", "Lisa"), 1);
|
||||
expectedCountsDrillDown.put(new CategoryPath("Author", "Bob"), 1);
|
||||
}
|
||||
|
||||
private void assertExpectedCounts(List<FacetResult> facetResults, ObjectToIntMap<CategoryPath> expCounts) {
|
||||
for (FacetResult res : facetResults) {
|
||||
FacetResultNode root = res.getFacetResultNode();
|
||||
for (FacetResultNode node : root.subResults) {
|
||||
assertEquals("incorrect count for " + node.label, expCounts.get(node.label), (int) node.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimple() throws Exception {
|
||||
List<FacetResult> facetResults = new SimpleFacetsExample().runSearch();
|
||||
assertEquals(2, facetResults.size());
|
||||
assertExpectedCounts(facetResults, expectedCounts);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDrillDown() throws Exception {
|
||||
List<FacetResult> facetResults = new SimpleFacetsExample().runDrillDown();
|
||||
assertEquals(1, facetResults.size());
|
||||
assertExpectedCounts(facetResults, expectedCountsDrillDown);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue