You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by dn...@apache.org on 2005/06/23 22:43:49 UTC
svn commit: r201453 - in /lucene/java/trunk/src:
java/org/apache/lucene/search/ test/org/apache/lucene/search/
Author: dnaber
Date: Thu Jun 23 13:43:47 2005
New Revision: 201453
URL: http://svn.apache.org/viewcvs?rev=201453&view=rev
Log:
Most of Wolf Siberski's patch to fix #35241/#31841: MulitSearcher failed on WildcardQuery etc.
-this has not been committed: removal of mergeBooleanQueries(); change to BooleanQuery.equals()
-added: a test case that is commented out which shows strange queries like "multi* multi* foo" don't work properly
Modified:
lucene/java/trunk/src/java/org/apache/lucene/search/BooleanQuery.java
lucene/java/trunk/src/java/org/apache/lucene/search/MultiTermQuery.java
lucene/java/trunk/src/java/org/apache/lucene/search/PrefixQuery.java
lucene/java/trunk/src/java/org/apache/lucene/search/Query.java
lucene/java/trunk/src/java/org/apache/lucene/search/RangeQuery.java
lucene/java/trunk/src/test/org/apache/lucene/search/TestMultiSearcherRanking.java
Modified: lucene/java/trunk/src/java/org/apache/lucene/search/BooleanQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/src/java/org/apache/lucene/search/BooleanQuery.java?rev=201453&r1=201452&r2=201453&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/BooleanQuery.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/BooleanQuery.java Thu Jun 23 13:43:47 2005
@@ -371,11 +371,6 @@
}
}
- // inherit javadoc
- public Query combine(Query[] queries) {
- return Query.mergeBooleanQueries(queries);
- }
-
public Object clone() {
BooleanQuery clone = (BooleanQuery)super.clone();
clone.clauses = (Vector)this.clauses.clone();
Modified: lucene/java/trunk/src/java/org/apache/lucene/search/MultiTermQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/src/java/org/apache/lucene/search/MultiTermQuery.java?rev=201453&r1=201452&r2=201453&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/MultiTermQuery.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/MultiTermQuery.java Thu Jun 23 13:43:47 2005
@@ -67,11 +67,6 @@
return query;
}
- public Query combine(Query[] queries) {
- return Query.mergeBooleanQueries(queries);
- }
-
-
/** Prints a user-readable version of this query. */
public String toString(String field) {
StringBuffer buffer = new StringBuffer();
Modified: lucene/java/trunk/src/java/org/apache/lucene/search/PrefixQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/src/java/org/apache/lucene/search/PrefixQuery.java?rev=201453&r1=201452&r2=201453&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/PrefixQuery.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/PrefixQuery.java Thu Jun 23 13:43:47 2005
@@ -60,10 +60,6 @@
return query;
}
- public Query combine(Query[] queries) {
- return Query.mergeBooleanQueries(queries);
- }
-
/** Prints a user-readable version of this query. */
public String toString(String field) {
StringBuffer buffer = new StringBuffer();
Modified: lucene/java/trunk/src/java/org/apache/lucene/search/Query.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/src/java/org/apache/lucene/search/Query.java?rev=201453&r1=201452&r2=201453&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/Query.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/Query.java Thu Jun 23 13:43:47 2005
@@ -104,16 +104,47 @@
/** Expert: called when re-writing queries under MultiSearcher.
*
- * <p>Only implemented by derived queries, with no
- * {@link #createWeight(Searcher)} implementation.
- */
+ * Create a single query suitable for use by all subsearchers (in 1-1
+ * correspondence with queries). This is an optimization of the OR of
+ * all queries. We handle the common optimization cases of equal
+ * queries and overlapping clauses of boolean OR queries (as generated
+ * by MultiTermQuery.rewrite() and RangeQuery.rewrite()).
+ * Be careful overriding this method as queries[0] determines which
+ * method will be called and is not necessarily of the same type as
+ * the other queries.
+ */
public Query combine(Query[] queries) {
- for (int i = 0; i < queries.length; i++) {
- if (!this.equals(queries[i])) {
- throw new IllegalArgumentException();
- }
+ HashSet uniques = new HashSet();
+ for (int i = 0; i < queries.length; i++) {
+ Query query = queries[i];
+ BooleanClause[] clauses = null;
+ // check if we can split the query into clauses
+ boolean splittable = (query instanceof BooleanQuery);
+ if(splittable){
+ BooleanQuery bq = (BooleanQuery) query;
+ splittable = bq.isCoordDisabled();
+ clauses = bq.getClauses();
+ for (int j = 0; splittable && j < clauses.length; j++) {
+ splittable = (clauses[j].getOccur() == BooleanClause.Occur.SHOULD);
}
- return this;
+ }
+ if(splittable){
+ for (int j = 0; j < clauses.length; j++) {
+ uniques.add(clauses[j].getQuery());
+ }
+ } else {
+ uniques.add(query);
+ }
+ }
+ // optimization: if we have just one query, just return it
+ if(uniques.size() == 1){
+ return (Query)uniques.iterator().next();
+ }
+ Iterator it = uniques.iterator();
+ BooleanQuery result = new BooleanQuery(true);
+ while (it.hasNext())
+ result.add((Query) it.next(), BooleanClause.Occur.SHOULD);
+ return result;
}
/**
Modified: lucene/java/trunk/src/java/org/apache/lucene/search/RangeQuery.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/src/java/org/apache/lucene/search/RangeQuery.java?rev=201453&r1=201452&r2=201453&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/RangeQuery.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/RangeQuery.java Thu Jun 23 13:43:47 2005
@@ -105,10 +105,6 @@
return query;
}
- public Query combine(Query[] queries) {
- return Query.mergeBooleanQueries(queries);
- }
-
/** Returns the field name for this query */
public String getField() {
return (lowerTerm != null ? lowerTerm.field() : upperTerm.field());
Modified: lucene/java/trunk/src/test/org/apache/lucene/search/TestMultiSearcherRanking.java
URL: http://svn.apache.org/viewcvs/lucene/java/trunk/src/test/org/apache/lucene/search/TestMultiSearcherRanking.java?rev=201453&r1=201452&r2=201453&view=diff
==============================================================================
--- lucene/java/trunk/src/test/org/apache/lucene/search/TestMultiSearcherRanking.java (original)
+++ lucene/java/trunk/src/test/org/apache/lucene/search/TestMultiSearcherRanking.java Thu Jun 23 13:43:47 2005
@@ -1,7 +1,7 @@
package org.apache.lucene.search;
/**
- * Copyright 2005 The Apache Software Foundation
+ * Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,8 @@
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.index.Term;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
@@ -34,70 +35,128 @@
*
* @version $Id: TestMultiSearcher.java 150492 2004-09-06 22:01:49Z dnaber $
*/
-public class TestMultiSearcherRanking extends TestCase
-{
-
- private final Query query = new TermQuery(new Term("body", "three"));
+public class TestMultiSearcherRanking extends TestCase {
- public void testMultiSearcherRanking() throws IOException {
- Hits multiSearcherHits = multi();
- Hits singleSearcherHits = single();
+ private final boolean verbose = false; // set to true to output hits
+ private final String FIELD_NAME = "body";
+ private Searcher multiSearcher;
+ private Searcher singleSearcher;
+
+ public void testOneTermQuery() throws IOException, ParseException {
+ checkQuery("three");
+ }
+
+ public void testTwoTermQuery() throws IOException, ParseException {
+ checkQuery("three foo");
+ }
+
+ public void testPrefixQuery() throws IOException, ParseException {
+ checkQuery("multi*");
+ }
+
+ public void testFuzzyQuery() throws IOException, ParseException {
+ checkQuery("multiThree~");
+ }
+
+ public void testRangeQuery() throws IOException, ParseException {
+ checkQuery("{multiA TO multiP}");
+ }
+
+ public void testMultiPhraseQuery() throws IOException, ParseException {
+ checkQuery("\"blueberry pi*\"");
+ }
+
+ public void testNoMatchQuery() throws IOException, ParseException {
+ checkQuery("+three +nomatch");
+ }
+
+ /*
+ public void testTermRepeatedQuery() throws IOException, ParseException {
+ // TODO: this corner case yields different results.
+ checkQuery("multi* multi* foo");
+ }
+ */
+
+ /**
+ * checks if a query yields the same result when executed on
+ * a single IndexSearcher containing all documents and on a
+ * MultiSearcher aggregating sub-searchers
+ * @param queryStr the query to check.
+ * @throws IOException
+ * @throws ParseException
+ */
+ private void checkQuery(String queryStr) throws IOException, ParseException {
+ // check result hit ranking
+ if(verbose) System.out.println("Query: " + queryStr);
+ Query query = QueryParser.parse(queryStr, FIELD_NAME,
+ new StandardAnalyzer());
+ Hits multiSearcherHits = multiSearcher.search(query);
+ Hits singleSearcherHits = singleSearcher.search(query);
assertEquals(multiSearcherHits.length(), singleSearcherHits.length());
- for(int i = 0; i < multiSearcherHits.length(); i++) {
- assertEquals(multiSearcherHits.score(i), singleSearcherHits.score(i), 0.001f);
+ for (int i = 0; i < multiSearcherHits.length(); i++) {
Document docMulti = multiSearcherHits.doc(i);
Document docSingle = singleSearcherHits.doc(i);
- assertEquals(docMulti.get("body"), docSingle.get("body"));
+ if(verbose) System.out.println("Multi: " + docMulti.get(FIELD_NAME) + " score="
+ + multiSearcherHits.score(i));
+ if(verbose) System.out.println("Single: " + docSingle.get(FIELD_NAME) + " score="
+ + singleSearcherHits.score(i));
+ assertEquals(multiSearcherHits.score(i), singleSearcherHits.score(i),
+ 0.001f);
+ assertEquals(docMulti.get(FIELD_NAME), docSingle.get(FIELD_NAME));
}
+ if(verbose) System.out.println();
}
-
- // Collection 1+2 searched with MultiSearcher:
- private Hits multi() throws IOException {
- Directory d1 = new RAMDirectory();
- IndexWriter iw = new IndexWriter(d1, new StandardAnalyzer(), true);
- addCollection1(iw);
- iw.close();
-
+
+ /**
+ * initializes multiSearcher and singleSearcher with the same document set
+ */
+ protected void setUp() throws Exception {
+ // create MultiSearcher from two seperate searchers
+ Directory d1 = new RAMDirectory();
+ IndexWriter iw1 = new IndexWriter(d1, new StandardAnalyzer(), true);
+ addCollection1(iw1);
+ iw1.close();
Directory d2 = new RAMDirectory();
- iw = new IndexWriter(d2, new StandardAnalyzer(), true);
- addCollection2(iw);
- iw.close();
-
+ IndexWriter iw2 = new IndexWriter(d2, new StandardAnalyzer(), true);
+ addCollection2(iw2);
+ iw2.close();
+
Searchable[] s = new Searchable[2];
s[0] = new IndexSearcher(d1);
s[1] = new IndexSearcher(d2);
- MultiSearcher ms = new MultiSearcher(s);
- Hits hits = ms.search(query);
- return hits;
- }
-
- // Collection 1+2 indexed together:
- private Hits single() throws IOException {
+ multiSearcher = new MultiSearcher(s);
+
+ // create IndexSearcher which contains all documents
Directory d = new RAMDirectory();
IndexWriter iw = new IndexWriter(d, new StandardAnalyzer(), true);
addCollection1(iw);
addCollection2(iw);
iw.close();
- IndexSearcher is = new IndexSearcher(d);
- Hits hits = is.search(query);
- return hits;
+ singleSearcher = new IndexSearcher(d);
}
-
+
private void addCollection1(IndexWriter iw) throws IOException {
add("one blah three", iw);
- add("one foo three", iw);
- add("one foobar three", iw);
+ add("one foo three multiOne", iw);
+ add("one foobar three multiThree", iw);
+ add("blueberry pie", iw);
+ add("blueberry strudel", iw);
+ add("blueberry pizza", iw);
}
-
+
private void addCollection2(IndexWriter iw) throws IOException {
add("two blah three", iw);
- add("two foo xxx", iw);
- add("two foobar xxx", iw);
+ add("two foo xxx multiTwo", iw);
+ add("two foobar xxx multiThreee", iw);
+ add("blueberry chewing gum", iw);
+ add("bluebird pizza", iw);
+ add("bluebird foobar pizza", iw);
+ add("piccadilly circus", iw);
}
-
+
private void add(String value, IndexWriter iw) throws IOException {
Document d = new Document();
- d.add(new Field("body", value, Field.Store.YES, Field.Index.TOKENIZED));
+ d.add(new Field(FIELD_NAME, value, Field.Store.YES, Field.Index.TOKENIZED));
iw.addDocument(d);
}