1 package org.apache.lucene.search;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import org.apache.lucene.util.LuceneTestCase;
21 import org.apache.lucene.analysis.standard.StandardAnalyzer;
22 import org.apache.lucene.document.Document;
23 import org.apache.lucene.document.Field;
24 import org.apache.lucene.index.IndexWriter;
25 import org.apache.lucene.queryParser.ParseException;
26 import org.apache.lucene.queryParser.QueryParser;
27 import org.apache.lucene.store.Directory;
28 import java.io.IOException;
31 * Tests {@link MultiSearcher} ranking, i.e. makes sure this bug is fixed:
32 * http://issues.apache.org/bugzilla/show_bug.cgi?id=31841
35 public class TestMultiSearcherRanking extends LuceneTestCase {
37 private final String FIELD_NAME = "body";
38 private Searcher multiSearcher;
39 private Searcher singleSearcher;
41 public void testOneTermQuery() throws IOException, ParseException {
45 public void testTwoTermQuery() throws IOException, ParseException {
46 checkQuery("three foo");
49 public void testPrefixQuery() throws IOException, ParseException {
53 public void testFuzzyQuery() throws IOException, ParseException {
54 checkQuery("multiThree~");
57 public void testRangeQuery() throws IOException, ParseException {
58 checkQuery("{multiA TO multiP}");
61 public void testMultiPhraseQuery() throws IOException, ParseException {
62 checkQuery("\"blueberry pi*\"");
65 public void testNoMatchQuery() throws IOException, ParseException {
66 checkQuery("+three +nomatch");
70 public void testTermRepeatedQuery() throws IOException, ParseException {
71 // TODO: this corner case yields different results.
72 checkQuery("multi* multi* foo");
77 * checks if a query yields the same result when executed on
78 * a single IndexSearcher containing all documents and on a
79 * MultiSearcher aggregating sub-searchers
80 * @param queryStr the query to check.
82 * @throws ParseException
84 private void checkQuery(String queryStr) throws IOException, ParseException {
85 // check result hit ranking
86 if(VERBOSE) System.out.println("Query: " + queryStr);
87 QueryParser queryParser = new QueryParser(TEST_VERSION_CURRENT, FIELD_NAME, new StandardAnalyzer(TEST_VERSION_CURRENT));
88 Query query = queryParser.parse(queryStr);
89 ScoreDoc[] multiSearcherHits = multiSearcher.search(query, null, 1000).scoreDocs;
90 ScoreDoc[] singleSearcherHits = singleSearcher.search(query, null, 1000).scoreDocs;
91 assertEquals(multiSearcherHits.length, singleSearcherHits.length);
92 for (int i = 0; i < multiSearcherHits.length; i++) {
93 Document docMulti = multiSearcher.doc(multiSearcherHits[i].doc);
94 Document docSingle = singleSearcher.doc(singleSearcherHits[i].doc);
95 if(VERBOSE) System.out.println("Multi: " + docMulti.get(FIELD_NAME) + " score="
96 + multiSearcherHits[i].score);
97 if(VERBOSE) System.out.println("Single: " + docSingle.get(FIELD_NAME) + " score="
98 + singleSearcherHits[i].score);
99 assertEquals(multiSearcherHits[i].score, singleSearcherHits[i].score,
101 assertEquals(docMulti.get(FIELD_NAME), docSingle.get(FIELD_NAME));
103 if(VERBOSE) System.out.println();
107 * initializes multiSearcher and singleSearcher with the same document set
110 public void setUp() throws Exception {
112 // create MultiSearcher from two seperate searchers
114 IndexWriter iw1 = new IndexWriter(d1, newIndexWriterConfig(TEST_VERSION_CURRENT, new StandardAnalyzer(TEST_VERSION_CURRENT)).setMergePolicy(newLogMergePolicy()));
118 IndexWriter iw2 = new IndexWriter(d2, newIndexWriterConfig(TEST_VERSION_CURRENT, new StandardAnalyzer(TEST_VERSION_CURRENT)).setMergePolicy(newLogMergePolicy()));
122 Searchable[] s = new Searchable[2];
123 s[0] = new IndexSearcher(d1, true);
124 s[1] = new IndexSearcher(d2, true);
125 multiSearcher = new MultiSearcher(s);
127 // create IndexSearcher which contains all documents
129 IndexWriter iw = new IndexWriter(d, newIndexWriterConfig(TEST_VERSION_CURRENT, new StandardAnalyzer(TEST_VERSION_CURRENT)).setMergePolicy(newLogMergePolicy()));
133 singleSearcher = new IndexSearcher(d, true);
139 public void tearDown() throws Exception {
140 multiSearcher.close();
141 singleSearcher.close();
148 private void addCollection1(IndexWriter iw) throws IOException {
149 add("one blah three", iw);
150 add("one foo three multiOne", iw);
151 add("one foobar three multiThree", iw);
152 add("blueberry pie", iw);
153 add("blueberry strudel", iw);
154 add("blueberry pizza", iw);
157 private void addCollection2(IndexWriter iw) throws IOException {
158 add("two blah three", iw);
159 add("two foo xxx multiTwo", iw);
160 add("two foobar xxx multiThreee", iw);
161 add("blueberry chewing gum", iw);
162 add("bluebird pizza", iw);
163 add("bluebird foobar pizza", iw);
164 add("piccadilly circus", iw);
167 private void add(String value, IndexWriter iw) throws IOException {
168 Document d = new Document();
169 d.add(newField(FIELD_NAME, value, Field.Store.YES, Field.Index.ANALYZED));