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

« back to all changes in this revision

Viewing changes to lucene/backwards/src/test/org/apache/lucene/search/TestCustomSearcherSort.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.search;
2
 
 
3
 
/**
4
 
 * Copyright 2005 The Apache Software Foundation
5
 
 *
6
 
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 
 * you may not use this file except in compliance with the License.
8
 
 * You may obtain a copy of the License at
9
 
 *
10
 
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 
 *
12
 
 * Unless required by applicable law or agreed to in writing, software
13
 
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 
 * See the License for the specific language governing permissions and
16
 
 * limitations under the License.
17
 
 */
18
 
 
19
 
import java.io.IOException;
20
 
import java.io.Serializable;
21
 
import java.util.Calendar;
22
 
import java.util.GregorianCalendar;
23
 
import java.util.Map;
24
 
import java.util.Random;
25
 
import java.util.TreeMap;
26
 
 
27
 
import org.apache.lucene.document.DateTools;
28
 
import org.apache.lucene.document.Document;
29
 
import org.apache.lucene.document.Field;
30
 
import org.apache.lucene.index.IndexReader;
31
 
import org.apache.lucene.index.RandomIndexWriter;
32
 
import org.apache.lucene.index.Term;
33
 
import org.apache.lucene.store.Directory;
34
 
import org.apache.lucene.util.LuceneTestCase;
35
 
 
36
 
/** Unit test for sorting code. */
37
 
public class TestCustomSearcherSort extends LuceneTestCase implements Serializable {
38
 
  
39
 
  private Directory index = null;
40
 
  private IndexReader reader;
41
 
  private Query query = null;
42
 
  // reduced from 20000 to 2000 to speed up test...
43
 
  private int INDEX_SIZE;
44
 
  
45
 
  /**
46
 
   * Create index and query for test cases.
47
 
   */
48
 
  @Override
49
 
  public void setUp() throws Exception {
50
 
    super.setUp();
51
 
    INDEX_SIZE = atLeast(2000);
52
 
    index = newDirectory();
53
 
    RandomIndexWriter writer = new RandomIndexWriter(random, index);
54
 
    RandomGen random = new RandomGen(this.random);
55
 
    for (int i = 0; i < INDEX_SIZE; ++i) { // don't decrease; if to low the
56
 
                                           // problem doesn't show up
57
 
      Document doc = new Document();
58
 
      if ((i % 5) != 0) { // some documents must not have an entry in the first
59
 
                          // sort field
60
 
        doc.add(newField("publicationDate_", random.getLuceneDate(),
61
 
            Field.Store.YES, Field.Index.NOT_ANALYZED));
62
 
      }
63
 
      if ((i % 7) == 0) { // some documents to match the query (see below)
64
 
        doc.add(newField("content", "test", Field.Store.YES,
65
 
            Field.Index.ANALYZED));
66
 
      }
67
 
      // every document has a defined 'mandant' field
68
 
      doc.add(newField("mandant", Integer.toString(i % 3), Field.Store.YES,
69
 
          Field.Index.NOT_ANALYZED));
70
 
      writer.addDocument(doc);
71
 
    }
72
 
    reader = writer.getReader();
73
 
    writer.close();
74
 
    query = new TermQuery(new Term("content", "test"));
75
 
  }
76
 
  
77
 
  @Override
78
 
  public void tearDown() throws Exception {
79
 
    reader.close();
80
 
    index.close();
81
 
    super.tearDown();
82
 
  }
83
 
  
84
 
  /**
85
 
   * Run the test using two CustomSearcher instances.
86
 
   */
87
 
  public void testFieldSortCustomSearcher() throws Exception {
88
 
    // log("Run testFieldSortCustomSearcher");
89
 
    // define the sort criteria
90
 
    Sort custSort = new Sort(
91
 
        new SortField("publicationDate_", SortField.STRING),
92
 
        SortField.FIELD_SCORE);
93
 
    Searcher searcher = new CustomSearcher(reader, 2);
94
 
    // search and check hits
95
 
    matchHits(searcher, custSort);
96
 
  }
97
 
  
98
 
  /**
99
 
   * Run the test using one CustomSearcher wrapped by a MultiSearcher.
100
 
   */
101
 
  public void testFieldSortSingleSearcher() throws Exception {
102
 
    // log("Run testFieldSortSingleSearcher");
103
 
    // define the sort criteria
104
 
    Sort custSort = new Sort(
105
 
        new SortField("publicationDate_", SortField.STRING),
106
 
        SortField.FIELD_SCORE);
107
 
    Searcher searcher = new MultiSearcher(new Searcher[] {new CustomSearcher(
108
 
        reader, 2)});
109
 
    // search and check hits
110
 
    matchHits(searcher, custSort);
111
 
  }
112
 
  
113
 
  /**
114
 
   * Run the test using two CustomSearcher instances.
115
 
   */
116
 
  public void testFieldSortMultiCustomSearcher() throws Exception {
117
 
    // log("Run testFieldSortMultiCustomSearcher");
118
 
    // define the sort criteria
119
 
    Sort custSort = new Sort(
120
 
        new SortField("publicationDate_", SortField.STRING),
121
 
        SortField.FIELD_SCORE);
122
 
    Searcher searcher = new MultiSearcher(new Searchable[] {
123
 
        new CustomSearcher(reader, 0), new CustomSearcher(reader, 2)});
124
 
    // search and check hits
125
 
    matchHits(searcher, custSort);
126
 
  }
127
 
  
128
 
  // make sure the documents returned by the search match the expected list
129
 
  private void matchHits(Searcher searcher, Sort sort) throws IOException {
130
 
    // make a query without sorting first
131
 
    ScoreDoc[] hitsByRank = searcher.search(query, null, Integer.MAX_VALUE).scoreDocs;
132
 
    checkHits(hitsByRank, "Sort by rank: "); // check for duplicates
133
 
    Map<Integer,Integer> resultMap = new TreeMap<Integer,Integer>();
134
 
    // store hits in TreeMap - TreeMap does not allow duplicates; existing
135
 
    // entries are silently overwritten
136
 
    for (int hitid = 0; hitid < hitsByRank.length; ++hitid) {
137
 
      resultMap.put(Integer.valueOf(hitsByRank[hitid].doc), // Key: Lucene
138
 
                                                            // Document ID
139
 
          Integer.valueOf(hitid)); // Value: Hits-Objekt Index
140
 
    }
141
 
    
142
 
    // now make a query using the sort criteria
143
 
    ScoreDoc[] resultSort = searcher.search(query, null, Integer.MAX_VALUE,
144
 
        sort).scoreDocs;
145
 
    checkHits(resultSort, "Sort by custom criteria: "); // check for duplicates
146
 
    
147
 
    // besides the sorting both sets of hits must be identical
148
 
    for (int hitid = 0; hitid < resultSort.length; ++hitid) {
149
 
      Integer idHitDate = Integer.valueOf(resultSort[hitid].doc); // document ID
150
 
                                                                  // from sorted
151
 
                                                                  // search
152
 
      if (!resultMap.containsKey(idHitDate)) {
153
 
        log("ID " + idHitDate + " not found. Possibliy a duplicate.");
154
 
      }
155
 
      assertTrue(resultMap.containsKey(idHitDate)); // same ID must be in the
156
 
                                                    // Map from the rank-sorted
157
 
                                                    // search
158
 
      // every hit must appear once in both result sets --> remove it from the
159
 
      // Map.
160
 
      // At the end the Map must be empty!
161
 
      resultMap.remove(idHitDate);
162
 
    }
163
 
    if (resultMap.size() == 0) {
164
 
      // log("All hits matched");
165
 
    } else {
166
 
      log("Couldn't match " + resultMap.size() + " hits.");
167
 
    }
168
 
    assertEquals(resultMap.size(), 0);
169
 
  }
170
 
  
171
 
  /**
172
 
   * Check the hits for duplicates.
173
 
   * 
174
 
   * @param hits
175
 
   */
176
 
  private void checkHits(ScoreDoc[] hits, String prefix) {
177
 
    if (hits != null) {
178
 
      Map<Integer,Integer> idMap = new TreeMap<Integer,Integer>();
179
 
      for (int docnum = 0; docnum < hits.length; ++docnum) {
180
 
        Integer luceneId = null;
181
 
        
182
 
        luceneId = Integer.valueOf(hits[docnum].doc);
183
 
        if (idMap.containsKey(luceneId)) {
184
 
          StringBuilder message = new StringBuilder(prefix);
185
 
          message.append("Duplicate key for hit index = ");
186
 
          message.append(docnum);
187
 
          message.append(", previous index = ");
188
 
          message.append((idMap.get(luceneId)).toString());
189
 
          message.append(", Lucene ID = ");
190
 
          message.append(luceneId);
191
 
          log(message.toString());
192
 
        } else {
193
 
          idMap.put(luceneId, Integer.valueOf(docnum));
194
 
        }
195
 
      }
196
 
    }
197
 
  }
198
 
  
199
 
  // Simply write to console - choosen to be independant of log4j etc
200
 
  private void log(String message) {
201
 
    if (VERBOSE) System.out.println(message);
202
 
  }
203
 
  
204
 
  public class CustomSearcher extends IndexSearcher {
205
 
    private int switcher;
206
 
    
207
 
    /**
208
 
     * @param r
209
 
     */
210
 
    public CustomSearcher(IndexReader r, int switcher) {
211
 
      super(r);
212
 
      this.switcher = switcher;
213
 
    }
214
 
    
215
 
    /*
216
 
     * (non-Javadoc)
217
 
     * 
218
 
     * @see
219
 
     * org.apache.lucene.search.Searchable#search(org.apache.lucene.search.Query
220
 
     * , org.apache.lucene.search.Filter, int, org.apache.lucene.search.Sort)
221
 
     */
222
 
    @Override
223
 
    public TopFieldDocs search(Query query, Filter filter, int nDocs, Sort sort)
224
 
        throws IOException {
225
 
      BooleanQuery bq = new BooleanQuery();
226
 
      bq.add(query, BooleanClause.Occur.MUST);
227
 
      bq.add(new TermQuery(new Term("mandant", Integer.toString(switcher))),
228
 
          BooleanClause.Occur.MUST);
229
 
      return super.search(bq, filter, nDocs, sort);
230
 
    }
231
 
    
232
 
    /*
233
 
     * (non-Javadoc)
234
 
     * 
235
 
     * @see
236
 
     * org.apache.lucene.search.Searchable#search(org.apache.lucene.search.Query
237
 
     * , org.apache.lucene.search.Filter, int)
238
 
     */
239
 
    @Override
240
 
    public TopDocs search(Query query, Filter filter, int nDocs)
241
 
        throws IOException {
242
 
      BooleanQuery bq = new BooleanQuery();
243
 
      bq.add(query, BooleanClause.Occur.MUST);
244
 
      bq.add(new TermQuery(new Term("mandant", Integer.toString(switcher))),
245
 
          BooleanClause.Occur.MUST);
246
 
      return super.search(bq, filter, nDocs);
247
 
    }
248
 
  }
249
 
  
250
 
  private class RandomGen {
251
 
    RandomGen(Random random) {
252
 
      this.random = random;
253
 
    }
254
 
    
255
 
    private Random random;
256
 
    private Calendar base = new GregorianCalendar(1980, 1, 1);
257
 
    
258
 
    // Just to generate some different Lucene Date strings
259
 
    private String getLuceneDate() {
260
 
      return DateTools.timeToString(base.getTimeInMillis() + random.nextInt()
261
 
          - Integer.MIN_VALUE, DateTools.Resolution.DAY);
262
 
    }
263
 
  }
264
 
}