~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to lucene/contrib/facet/src/test/org/apache/lucene/facet/search/params/MultiIteratorsPerCLParamsTest.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package org.apache.lucene.facet.search.params;
2
 
 
3
 
import java.io.IOException;
4
 
import java.util.Arrays;
5
 
import java.util.List;
6
 
 
7
 
import org.apache.lucene.analysis.MockAnalyzer;
8
 
import org.apache.lucene.analysis.MockTokenizer;
9
 
import org.apache.lucene.document.Document;
10
 
import org.apache.lucene.index.CorruptIndexException;
11
 
import org.apache.lucene.index.IndexReader;
12
 
import org.apache.lucene.index.RandomIndexWriter;
13
 
import org.apache.lucene.store.Directory;
14
 
import org.junit.Test;
15
 
 
16
 
import org.apache.lucene.util.LuceneTestCase;
17
 
import org.apache.lucene.facet.index.CategoryDocumentBuilder;
18
 
import org.apache.lucene.facet.index.params.CategoryListParams;
19
 
import org.apache.lucene.facet.index.params.DefaultFacetIndexingParams;
20
 
import org.apache.lucene.facet.index.params.FacetIndexingParams;
21
 
import org.apache.lucene.facet.search.CategoryListIterator;
22
 
import org.apache.lucene.facet.search.FacetArrays;
23
 
import org.apache.lucene.facet.search.FacetResultsHandler;
24
 
import org.apache.lucene.facet.search.FacetsAccumulator;
25
 
import org.apache.lucene.facet.search.ScoredDocIDs;
26
 
import org.apache.lucene.facet.search.StandardFacetsAccumulator;
27
 
import org.apache.lucene.facet.search.TopKFacetResultsHandler;
28
 
import org.apache.lucene.facet.search.cache.CategoryListCache;
29
 
import org.apache.lucene.facet.search.results.FacetResult;
30
 
import org.apache.lucene.facet.search.results.FacetResultNode;
31
 
import org.apache.lucene.facet.search.results.IntermediateFacetResult;
32
 
import org.apache.lucene.facet.taxonomy.CategoryPath;
33
 
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
34
 
import org.apache.lucene.facet.taxonomy.TaxonomyWriter;
35
 
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
36
 
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
37
 
import org.apache.lucene.facet.util.ScoredDocIdsUtils;
38
 
 
39
 
/**
40
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
41
 
 * contributor license agreements.  See the NOTICE file distributed with
42
 
 * this work for additional information regarding copyright ownership.
43
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
44
 
 * (the "License"); you may not use this file except in compliance with
45
 
 * the License.  You may obtain a copy of the License at
46
 
 *
47
 
 *     http://www.apache.org/licenses/LICENSE-2.0
48
 
 *
49
 
 * Unless required by applicable law or agreed to in writing, software
50
 
 * distributed under the License is distributed on an "AS IS" BASIS,
51
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
52
 
 * See the License for the specific language governing permissions and
53
 
 * limitations under the License.
54
 
 */
55
 
 
56
 
/**
57
 
 * Test faceted search with creation of multiple category list iterators by the
58
 
 * same CLP, depending on the provided facet request
59
 
 */
60
 
public class MultiIteratorsPerCLParamsTest extends LuceneTestCase {
61
 
 
62
 
  CategoryPath[][] perDocCategories = new CategoryPath[][] {
63
 
      { new CategoryPath("author", "Mark Twain"),
64
 
          new CategoryPath("date", "2010") },
65
 
      { new CategoryPath("author", "Robert Frost"),
66
 
          new CategoryPath("date", "2009") },
67
 
      { new CategoryPath("author", "Artur Miller"),
68
 
          new CategoryPath("date", "2010") },
69
 
      { new CategoryPath("author", "Edgar Allan Poe"),
70
 
          new CategoryPath("date", "2009") },
71
 
      { new CategoryPath("author", "Henry James"),
72
 
          new CategoryPath("date", "2010") } };
73
 
  
74
 
  String countForbiddenDimension;
75
 
 
76
 
  @Test
77
 
  public void testCLParamMultiIteratorsByRequest() throws Exception {
78
 
    doTestCLParamMultiIteratorsByRequest(false);
79
 
  }
80
 
 
81
 
  @Test
82
 
  public void testCLParamMultiIteratorsByRequestCacheCLI() throws Exception {
83
 
    doTestCLParamMultiIteratorsByRequest(true);
84
 
  }
85
 
 
86
 
  private void doTestCLParamMultiIteratorsByRequest(boolean cacheCLI) throws Exception,
87
 
      CorruptIndexException, IOException {
88
 
    // Create a CLP which generates different CLIs according to the
89
 
    // FacetRequest's dimension
90
 
    CategoryListParams clp = new CategoryListParams();
91
 
    FacetIndexingParams iParams = new DefaultFacetIndexingParams(clp);
92
 
    Directory indexDir = newDirectory();
93
 
    Directory taxoDir = newDirectory();
94
 
    populateIndex(iParams, indexDir, taxoDir);
95
 
 
96
 
    TaxonomyReader taxo = new DirectoryTaxonomyReader(taxoDir);
97
 
    IndexReader reader = IndexReader.open(indexDir);
98
 
 
99
 
    CategoryListCache clCache = null;
100
 
    if (cacheCLI) {
101
 
      // caching the iteratorr, so:
102
 
      // 1: create the cached iterator, using original params
103
 
      clCache = new CategoryListCache();
104
 
      clCache.loadAndRegister(clp, reader, taxo, iParams);
105
 
    }
106
 
    
107
 
    ScoredDocIDs allDocs = ScoredDocIdsUtils
108
 
        .createAllDocsScoredDocIDs(reader);
109
 
 
110
 
    // Search index with 'author' should filter ONLY ordinals whose parent
111
 
    // is 'author'
112
 
    countForbiddenDimension = "date";
113
 
    validateFacetedSearch(iParams, taxo, reader, clCache, allDocs, "author", 5, 5);
114
 
 
115
 
    // Search index with 'date' should filter ONLY ordinals whose parent is
116
 
    // 'date'
117
 
    countForbiddenDimension = "author";
118
 
    validateFacetedSearch(iParams, taxo, reader, clCache, allDocs, "date", 5, 2);
119
 
 
120
 
    // Search index with both 'date' and 'author'
121
 
    countForbiddenDimension = null;
122
 
    validateFacetedSearch(iParams, taxo, reader, clCache, allDocs, new String[] {
123
 
            "author", "date" }, new int[] { 5, 5 }, new int[] { 5, 2 });
124
 
    taxo.close();
125
 
    reader.close();
126
 
    indexDir.close();
127
 
    taxoDir.close();
128
 
  }
129
 
 
130
 
  private void validateFacetedSearch(FacetIndexingParams iParams,
131
 
      TaxonomyReader taxo, IndexReader reader, CategoryListCache clCache,
132
 
      ScoredDocIDs allDocs, String dimension, int expectedValue, int expectedNumDescendants) throws IOException {
133
 
    validateFacetedSearch(iParams, taxo, reader, clCache, allDocs,
134
 
        new String[] { dimension }, new int[] { expectedValue },
135
 
        new int[] { expectedNumDescendants });
136
 
  }
137
 
 
138
 
  private void validateFacetedSearch(FacetIndexingParams iParams,
139
 
      TaxonomyReader taxo, IndexReader reader,  CategoryListCache clCache, ScoredDocIDs allDocs,
140
 
      String[] dimension, int[] expectedValue,
141
 
      int[] expectedNumDescendants)
142
 
      throws IOException {
143
 
    FacetSearchParams sParams = new FacetSearchParams(iParams);
144
 
    sParams.setClCache(clCache);
145
 
    for (String dim : dimension) {
146
 
      sParams.addFacetRequest(new PerDimCountFacetRequest(
147
 
          new CategoryPath(dim), 10));
148
 
    }
149
 
    FacetsAccumulator acc = new StandardFacetsAccumulator(sParams, reader, taxo);
150
 
    
151
 
    // no use to test this with complement since at that mode all facets are taken
152
 
    acc.setComplementThreshold(FacetsAccumulator.DISABLE_COMPLEMENT);
153
 
 
154
 
    List<FacetResult> results = acc.accumulate(allDocs);
155
 
    assertEquals("Wrong #results", dimension.length, results.size());
156
 
 
157
 
    for (int i = 0; i < results.size(); i++) {
158
 
      FacetResult res = results.get(i);
159
 
      assertEquals("wrong num-descendants for dimension " + dimension[i],
160
 
          expectedNumDescendants[i], res.getNumValidDescendants());
161
 
      FacetResultNode resNode = res.getFacetResultNode();
162
 
      assertEquals("wrong value for dimension " + dimension[i],
163
 
          expectedValue[i], (int) resNode.getValue());
164
 
    }
165
 
  }
166
 
 
167
 
  private void populateIndex(FacetIndexingParams iParams, Directory indexDir,
168
 
      Directory taxoDir) throws Exception {
169
 
    RandomIndexWriter writer = new RandomIndexWriter(random, indexDir, 
170
 
        newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random, MockTokenizer.KEYWORD, false)));
171
 
    TaxonomyWriter taxoWriter = new DirectoryTaxonomyWriter(taxoDir);
172
 
 
173
 
    for (CategoryPath[] categories : perDocCategories) {
174
 
      writer.addDocument(new CategoryDocumentBuilder(taxoWriter, iParams)
175
 
          .setCategoryPaths(Arrays.asList(categories)).build(
176
 
              new Document()));
177
 
 
178
 
    }
179
 
    taxoWriter.commit();
180
 
    writer.commit();
181
 
    taxoWriter.close();
182
 
    writer.close();
183
 
  }
184
 
 
185
 
  private class PerDimCountFacetRequest extends CountFacetRequest {
186
 
    
187
 
    public PerDimCountFacetRequest(CategoryPath path, int num) {
188
 
      super(path, num);
189
 
    }
190
 
 
191
 
    @Override
192
 
    public CategoryListIterator createCategoryListIterator(IndexReader reader, 
193
 
        TaxonomyReader taxo, FacetSearchParams sParams, int partition) throws IOException {
194
 
      // categories of certain dimension only
195
 
      return new PerDimensionCLI(taxo, super.createCategoryListIterator(
196
 
          reader, taxo, sParams, partition), getCategoryPath());
197
 
    }
198
 
    
199
 
    @Override
200
 
    /** Override this method just for verifying that only specified facets are iterated.. */
201
 
    public FacetResultsHandler createFacetResultsHandler(
202
 
        TaxonomyReader taxonomyReader) {
203
 
      return new TopKFacetResultsHandler(taxonomyReader, this) {
204
 
        @Override
205
 
        public IntermediateFacetResult fetchPartitionResult(
206
 
            FacetArrays facetArrays, int offset) throws IOException {
207
 
          final IntermediateFacetResult res = super.fetchPartitionResult(facetArrays, offset);
208
 
          if (countForbiddenDimension!=null) {
209
 
            int ord = taxonomyReader.getOrdinal(new CategoryPath(countForbiddenDimension));
210
 
            assertEquals("Should not have accumulated for dimension '"+countForbiddenDimension+"'!",0,facetArrays.getIntArray()[ord]);
211
 
          }
212
 
          return res;
213
 
        }
214
 
      };
215
 
    }
216
 
  }
217
 
 
218
 
  /**
219
 
   * a CLI which filters another CLI for the dimension of the provided
220
 
   * category-path
221
 
   */
222
 
  private static class PerDimensionCLI implements CategoryListIterator {
223
 
    private final CategoryListIterator superCLI;
224
 
    private final int[] parentArray;
225
 
    private final int parentOrdinal;
226
 
 
227
 
    PerDimensionCLI(TaxonomyReader taxo, CategoryListIterator superCLI,
228
 
        CategoryPath requestedPath) throws IOException {
229
 
      this.superCLI = superCLI;
230
 
      if (requestedPath == null) {
231
 
        parentOrdinal = 0;
232
 
      } else {
233
 
        CategoryPath cp = new CategoryPath(requestedPath.getComponent(0));
234
 
        parentOrdinal = taxo.getOrdinal(cp);
235
 
      }
236
 
      parentArray = taxo.getParentArray();
237
 
    }
238
 
 
239
 
    public boolean init() throws IOException {
240
 
      return superCLI.init();
241
 
    }
242
 
 
243
 
    public long nextCategory() throws IOException {
244
 
      long next;
245
 
      while ((next = superCLI.nextCategory()) <= Integer.MAX_VALUE
246
 
          && !isInDimension((int) next)) {
247
 
      }
248
 
 
249
 
      return next;
250
 
    }
251
 
 
252
 
    /** look for original parent ordinal, meaning same dimension */
253
 
    private boolean isInDimension(int ordinal) {
254
 
      while (ordinal > 0) {
255
 
        if (ordinal == parentOrdinal) {
256
 
          return true;
257
 
        }
258
 
        ordinal = parentArray[ordinal];
259
 
      }
260
 
      return false;
261
 
    }
262
 
 
263
 
    public boolean skipTo(int docId) throws IOException {
264
 
      return superCLI.skipTo(docId);
265
 
    }
266
 
  }
267
 
}
 
 
b'\\ No newline at end of file'