| /* |
| * 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. |
| */ |
| package org.apache.lucene.facet; |
| |
| import java.io.IOException; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.apache.lucene.analysis.MockAnalyzer; |
| import org.apache.lucene.analysis.MockTokenizer; |
| import org.apache.lucene.document.Document; |
| import org.apache.lucene.document.Field; |
| import org.apache.lucene.document.TextField; |
| import org.apache.lucene.facet.taxonomy.TaxonomyReader; |
| import org.apache.lucene.facet.taxonomy.TaxonomyWriter; |
| import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader; |
| import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter; |
| import org.apache.lucene.index.LeafReader; |
| import org.apache.lucene.index.LeafReaderContext; |
| import org.apache.lucene.index.IndexReader; |
| import org.apache.lucene.index.IndexWriterConfig.OpenMode; |
| import org.apache.lucene.index.RandomIndexWriter; |
| import org.apache.lucene.search.IndexSearcher; |
| import org.apache.lucene.search.MatchAllDocsQuery; |
| import org.apache.lucene.store.Directory; |
| import org.apache.lucene.util.IOUtils; |
| import org.junit.Test; |
| |
| public class TestMultipleIndexFields extends FacetTestCase { |
| |
| private static final FacetField[] CATEGORIES = new FacetField[] { |
| new FacetField("Author", "Mark Twain"), |
| new FacetField("Author", "Stephen King"), |
| new FacetField("Author", "Kurt Vonnegut"), |
| new FacetField("Band", "Rock & Pop", "The Beatles"), |
| new FacetField("Band", "Punk", "The Ramones"), |
| new FacetField("Band", "Rock & Pop", "U2"), |
| new FacetField("Band", "Rock & Pop", "REM"), |
| new FacetField("Band", "Rock & Pop", "Dave Matthews Band"), |
| new FacetField("Composer", "Bach"), |
| }; |
| |
| private FacetsConfig getConfig() { |
| FacetsConfig config = new FacetsConfig(); |
| config.setHierarchical("Band", true); |
| return config; |
| } |
| |
| @Test |
| public void testDefault() throws Exception { |
| Directory indexDir = newDirectory(); |
| Directory taxoDir = newDirectory(); |
| |
| // create and open an index writer |
| RandomIndexWriter iw = new RandomIndexWriter(random(), indexDir, newIndexWriterConfig( |
| new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false))); |
| // create and open a taxonomy writer |
| TaxonomyWriter tw = new DirectoryTaxonomyWriter(taxoDir, OpenMode.CREATE); |
| FacetsConfig config = getConfig(); |
| |
| seedIndex(tw, iw, config); |
| |
| IndexReader ir = iw.getReader(); |
| tw.commit(); |
| |
| // prepare index reader and taxonomy. |
| TaxonomyReader tr = new DirectoryTaxonomyReader(taxoDir); |
| |
| // prepare searcher to search against |
| IndexSearcher searcher = newSearcher(ir); |
| |
| FacetsCollector sfc = performSearch(tr, ir, searcher); |
| |
| // Obtain facets results and hand-test them |
| assertCorrectResults(getTaxonomyFacetCounts(tr, config, sfc)); |
| |
| assertOrdinalsExist("$facets", ir); |
| |
| iw.close(); |
| IOUtils.close(tr, ir, tw, indexDir, taxoDir); |
| } |
| |
| @Test |
| public void testCustom() throws Exception { |
| Directory indexDir = newDirectory(); |
| Directory taxoDir = newDirectory(); |
| |
| // create and open an index writer |
| RandomIndexWriter iw = new RandomIndexWriter(random(), indexDir, newIndexWriterConfig( |
| new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false))); |
| // create and open a taxonomy writer |
| TaxonomyWriter tw = new DirectoryTaxonomyWriter(taxoDir, OpenMode.CREATE); |
| |
| FacetsConfig config = getConfig(); |
| config.setIndexFieldName("Author", "$author"); |
| seedIndex(tw, iw, config); |
| |
| IndexReader ir = iw.getReader(); |
| tw.commit(); |
| |
| // prepare index reader and taxonomy. |
| TaxonomyReader tr = new DirectoryTaxonomyReader(taxoDir); |
| |
| // prepare searcher to search against |
| IndexSearcher searcher = newSearcher(ir); |
| |
| FacetsCollector sfc = performSearch(tr, ir, searcher); |
| |
| Map<String,Facets> facetsMap = new HashMap<>(); |
| facetsMap.put("Author", getTaxonomyFacetCounts(tr, config, sfc, "$author")); |
| Facets facets = new MultiFacets(facetsMap, getTaxonomyFacetCounts(tr, config, sfc)); |
| |
| // Obtain facets results and hand-test them |
| assertCorrectResults(facets); |
| |
| assertOrdinalsExist("$facets", ir); |
| assertOrdinalsExist("$author", ir); |
| |
| iw.close(); |
| IOUtils.close(tr, ir, tw, indexDir, taxoDir); |
| } |
| |
| @Test |
| public void testTwoCustomsSameField() throws Exception { |
| Directory indexDir = newDirectory(); |
| Directory taxoDir = newDirectory(); |
| |
| // create and open an index writer |
| RandomIndexWriter iw = new RandomIndexWriter(random(), indexDir, newIndexWriterConfig( |
| new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false))); |
| // create and open a taxonomy writer |
| TaxonomyWriter tw = new DirectoryTaxonomyWriter(taxoDir, OpenMode.CREATE); |
| |
| FacetsConfig config = getConfig(); |
| config.setIndexFieldName("Band", "$music"); |
| config.setIndexFieldName("Composer", "$music"); |
| seedIndex(tw, iw, config); |
| |
| IndexReader ir = iw.getReader(); |
| tw.commit(); |
| |
| // prepare index reader and taxonomy. |
| TaxonomyReader tr = new DirectoryTaxonomyReader(taxoDir); |
| |
| // prepare searcher to search against |
| IndexSearcher searcher = newSearcher(ir); |
| |
| FacetsCollector sfc = performSearch(tr, ir, searcher); |
| |
| Map<String,Facets> facetsMap = new HashMap<>(); |
| Facets facets2 = getTaxonomyFacetCounts(tr, config, sfc, "$music"); |
| facetsMap.put("Band", facets2); |
| facetsMap.put("Composer", facets2); |
| Facets facets = new MultiFacets(facetsMap, getTaxonomyFacetCounts(tr, config, sfc)); |
| |
| // Obtain facets results and hand-test them |
| assertCorrectResults(facets); |
| |
| assertOrdinalsExist("$facets", ir); |
| assertOrdinalsExist("$music", ir); |
| assertOrdinalsExist("$music", ir); |
| |
| iw.close(); |
| IOUtils.close(tr, ir, tw, indexDir, taxoDir); |
| } |
| |
| private void assertOrdinalsExist(String field, IndexReader ir) throws IOException { |
| for (LeafReaderContext context : ir.leaves()) { |
| LeafReader r = context.reader(); |
| if (r.getBinaryDocValues(field) != null) { |
| return; // not all segments must have this DocValues |
| } |
| } |
| fail("no ordinals found for " + field); |
| } |
| |
| @Test |
| public void testDifferentFieldsAndText() throws Exception { |
| Directory indexDir = newDirectory(); |
| Directory taxoDir = newDirectory(); |
| |
| // create and open an index writer |
| RandomIndexWriter iw = new RandomIndexWriter(random(), indexDir, newIndexWriterConfig( |
| new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false))); |
| // create and open a taxonomy writer |
| TaxonomyWriter tw = new DirectoryTaxonomyWriter(taxoDir, OpenMode.CREATE); |
| |
| FacetsConfig config = getConfig(); |
| config.setIndexFieldName("Band", "$bands"); |
| config.setIndexFieldName("Composer", "$composers"); |
| seedIndex(tw, iw, config); |
| |
| IndexReader ir = iw.getReader(); |
| tw.commit(); |
| |
| // prepare index reader and taxonomy. |
| TaxonomyReader tr = new DirectoryTaxonomyReader(taxoDir); |
| |
| // prepare searcher to search against |
| IndexSearcher searcher = newSearcher(ir); |
| |
| FacetsCollector sfc = performSearch(tr, ir, searcher); |
| |
| Map<String,Facets> facetsMap = new HashMap<>(); |
| facetsMap.put("Band", getTaxonomyFacetCounts(tr, config, sfc, "$bands")); |
| facetsMap.put("Composer", getTaxonomyFacetCounts(tr, config, sfc, "$composers")); |
| Facets facets = new MultiFacets(facetsMap, getTaxonomyFacetCounts(tr, config, sfc)); |
| |
| // Obtain facets results and hand-test them |
| assertCorrectResults(facets); |
| assertOrdinalsExist("$facets", ir); |
| assertOrdinalsExist("$bands", ir); |
| assertOrdinalsExist("$composers", ir); |
| |
| iw.close(); |
| IOUtils.close(tr, ir, tw, indexDir, taxoDir); |
| } |
| |
| @Test |
| public void testSomeSameSomeDifferent() throws Exception { |
| Directory indexDir = newDirectory(); |
| Directory taxoDir = newDirectory(); |
| |
| // create and open an index writer |
| RandomIndexWriter iw = new RandomIndexWriter(random(), indexDir, newIndexWriterConfig( |
| new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false))); |
| // create and open a taxonomy writer |
| TaxonomyWriter tw = new DirectoryTaxonomyWriter(taxoDir, OpenMode.CREATE); |
| |
| FacetsConfig config = getConfig(); |
| config.setIndexFieldName("Band", "$music"); |
| config.setIndexFieldName("Composer", "$music"); |
| config.setIndexFieldName("Author", "$literature"); |
| seedIndex(tw, iw, config); |
| |
| IndexReader ir = iw.getReader(); |
| tw.commit(); |
| |
| // prepare index reader and taxonomy. |
| TaxonomyReader tr = new DirectoryTaxonomyReader(taxoDir); |
| |
| // prepare searcher to search against |
| IndexSearcher searcher = newSearcher(ir); |
| |
| FacetsCollector sfc = performSearch(tr, ir, searcher); |
| |
| Map<String,Facets> facetsMap = new HashMap<>(); |
| Facets facets2 = getTaxonomyFacetCounts(tr, config, sfc, "$music"); |
| facetsMap.put("Band", facets2); |
| facetsMap.put("Composer", facets2); |
| facetsMap.put("Author", getTaxonomyFacetCounts(tr, config, sfc, "$literature")); |
| Facets facets = new MultiFacets(facetsMap, getTaxonomyFacetCounts(tr, config, sfc)); |
| |
| // Obtain facets results and hand-test them |
| assertCorrectResults(facets); |
| assertOrdinalsExist("$music", ir); |
| assertOrdinalsExist("$literature", ir); |
| |
| iw.close(); |
| IOUtils.close(tr, ir, iw, tw, indexDir, taxoDir); |
| } |
| |
| private void assertCorrectResults(Facets facets) throws IOException { |
| assertEquals(5, facets.getSpecificValue("Band")); |
| assertEquals("dim=Band path=[] value=5 childCount=2\n Rock & Pop (4)\n Punk (1)\n", facets.getTopChildren(10, "Band").toString()); |
| assertEquals("dim=Band path=[Rock & Pop] value=4 childCount=4\n The Beatles (1)\n U2 (1)\n REM (1)\n Dave Matthews Band (1)\n", facets.getTopChildren(10, "Band", "Rock & Pop").toString()); |
| assertEquals("dim=Author path=[] value=3 childCount=3\n Mark Twain (1)\n Stephen King (1)\n Kurt Vonnegut (1)\n", facets.getTopChildren(10, "Author").toString()); |
| } |
| |
| private FacetsCollector performSearch(TaxonomyReader tr, IndexReader ir, |
| IndexSearcher searcher) throws IOException { |
| FacetsCollector fc = new FacetsCollector(); |
| FacetsCollector.search(searcher, new MatchAllDocsQuery(), 10, fc); |
| return fc; |
| } |
| |
| private void seedIndex(TaxonomyWriter tw, RandomIndexWriter iw, FacetsConfig config) throws IOException { |
| for (FacetField ff : CATEGORIES) { |
| Document doc = new Document(); |
| doc.add(ff); |
| doc.add(new TextField("content", "alpha", Field.Store.YES)); |
| iw.addDocument(config.build(tw, doc)); |
| } |
| } |
| } |