mirror of https://github.com/apache/lucene.git
LUCENE-1028: Fixed Weight serialization for few queries.
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@587050 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2f5507bfc9
commit
1df7007219
|
@ -127,6 +127,11 @@ Bug fixes
|
||||||
sharing an index over NFS, can be writers in quick succession.
|
sharing an index over NFS, can be writers in quick succession.
|
||||||
(Patrick Kimber vis Mike McCandless)
|
(Patrick Kimber vis Mike McCandless)
|
||||||
|
|
||||||
|
21. LUCENE-1028: Fixed Weight serialization for few queries:
|
||||||
|
DisjunctionMaxQuery, ValueSourceQuery, CustomScoreQuery.
|
||||||
|
Serialization check added for all queries.
|
||||||
|
(Kyle Maxwell via Doron Cohen)
|
||||||
|
|
||||||
New features
|
New features
|
||||||
|
|
||||||
1. LUCENE-906: Elision filter for French.
|
1. LUCENE-906: Elision filter for French.
|
||||||
|
|
|
@ -89,12 +89,12 @@ public class DisjunctionMaxQuery extends Query {
|
||||||
/* The Weight for DisjunctionMaxQuery's, used to normalize, score and explain these queries */
|
/* The Weight for DisjunctionMaxQuery's, used to normalize, score and explain these queries */
|
||||||
private class DisjunctionMaxWeight implements Weight {
|
private class DisjunctionMaxWeight implements Weight {
|
||||||
|
|
||||||
private Searcher searcher; // The searcher with which we are associated.
|
private Similarity similarity; // The similarity which we are associated.
|
||||||
private ArrayList weights = new ArrayList(); // The Weight's for our subqueries, in 1-1 correspondence with disjuncts
|
private ArrayList weights = new ArrayList(); // The Weight's for our subqueries, in 1-1 correspondence with disjuncts
|
||||||
|
|
||||||
/* Construct the Weight for this Query searched by searcher. Recursively construct subquery weights. */
|
/* Construct the Weight for this Query searched by searcher. Recursively construct subquery weights. */
|
||||||
public DisjunctionMaxWeight(Searcher searcher) throws IOException {
|
public DisjunctionMaxWeight(Searcher searcher) throws IOException {
|
||||||
this.searcher = searcher;
|
this.similarity = searcher.getSimilarity();
|
||||||
for (int i = 0; i < disjuncts.size(); i++)
|
for (int i = 0; i < disjuncts.size(); i++)
|
||||||
weights.add(((Query) disjuncts.get(i)).createWeight(searcher));
|
weights.add(((Query) disjuncts.get(i)).createWeight(searcher));
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ public class DisjunctionMaxQuery extends Query {
|
||||||
|
|
||||||
/* Create the scorer used to score our associated DisjunctionMaxQuery */
|
/* Create the scorer used to score our associated DisjunctionMaxQuery */
|
||||||
public Scorer scorer(IndexReader reader) throws IOException {
|
public Scorer scorer(IndexReader reader) throws IOException {
|
||||||
DisjunctionMaxScorer result = new DisjunctionMaxScorer(tieBreakerMultiplier, getSimilarity(searcher));
|
DisjunctionMaxScorer result = new DisjunctionMaxScorer(tieBreakerMultiplier, similarity);
|
||||||
for (int i = 0 ; i < weights.size(); i++) {
|
for (int i = 0 ; i < weights.size(); i++) {
|
||||||
Weight w = (Weight) weights.get(i);
|
Weight w = (Weight) weights.get(i);
|
||||||
Scorer subScorer = w.scorer(reader);
|
Scorer subScorer = w.scorer(reader);
|
||||||
|
|
|
@ -172,13 +172,13 @@ public class CustomScoreQuery extends Query {
|
||||||
//=========================== W E I G H T ============================
|
//=========================== W E I G H T ============================
|
||||||
|
|
||||||
private class CustomWeight implements Weight {
|
private class CustomWeight implements Weight {
|
||||||
Searcher searcher;
|
Similarity similarity;
|
||||||
Weight subQueryWeight;
|
Weight subQueryWeight;
|
||||||
Weight valSrcWeight; // optional
|
Weight valSrcWeight; // optional
|
||||||
boolean qStrict;
|
boolean qStrict;
|
||||||
|
|
||||||
public CustomWeight(Searcher searcher) throws IOException {
|
public CustomWeight(Searcher searcher) throws IOException {
|
||||||
this.searcher = searcher;
|
this.similarity = getSimilarity(searcher);
|
||||||
this.subQueryWeight = subQuery.weight(searcher);
|
this.subQueryWeight = subQuery.weight(searcher);
|
||||||
if (valSrcQuery!=null) {
|
if (valSrcQuery!=null) {
|
||||||
this.valSrcWeight = valSrcQuery.createWeight(searcher);
|
this.valSrcWeight = valSrcQuery.createWeight(searcher);
|
||||||
|
@ -227,7 +227,7 @@ public class CustomScoreQuery extends Query {
|
||||||
public Scorer scorer(IndexReader reader) throws IOException {
|
public Scorer scorer(IndexReader reader) throws IOException {
|
||||||
Scorer subQueryScorer = subQueryWeight.scorer(reader);
|
Scorer subQueryScorer = subQueryWeight.scorer(reader);
|
||||||
Scorer valSrcScorer = (valSrcWeight==null ? null : valSrcWeight.scorer(reader));
|
Scorer valSrcScorer = (valSrcWeight==null ? null : valSrcWeight.scorer(reader));
|
||||||
return new CustomScorer(getSimilarity(searcher), reader, this, subQueryScorer, valSrcScorer);
|
return new CustomScorer(similarity, reader, this, subQueryScorer, valSrcScorer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */
|
/*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */
|
||||||
|
|
|
@ -43,7 +43,6 @@ import org.apache.lucene.search.FieldCache;
|
||||||
*/
|
*/
|
||||||
public abstract class FieldCacheSource extends ValueSource {
|
public abstract class FieldCacheSource extends ValueSource {
|
||||||
private String field;
|
private String field;
|
||||||
private FieldCache cache = FieldCache.DEFAULT;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a cached field source for the input field.
|
* Create a cached field source for the input field.
|
||||||
|
@ -54,7 +53,7 @@ public abstract class FieldCacheSource extends ValueSource {
|
||||||
|
|
||||||
/* (non-Javadoc) @see org.apache.lucene.search.function.ValueSource#getValues(org.apache.lucene.index.IndexReader) */
|
/* (non-Javadoc) @see org.apache.lucene.search.function.ValueSource#getValues(org.apache.lucene.index.IndexReader) */
|
||||||
public final DocValues getValues(IndexReader reader) throws IOException {
|
public final DocValues getValues(IndexReader reader) throws IOException {
|
||||||
return getCachedFieldValues(cache, field, reader);
|
return getCachedFieldValues(FieldCache.DEFAULT, field, reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc) @see org.apache.lucene.search.function.ValueSource#description() */
|
/* (non-Javadoc) @see org.apache.lucene.search.function.ValueSource#description() */
|
||||||
|
@ -77,7 +76,6 @@ public abstract class FieldCacheSource extends ValueSource {
|
||||||
}
|
}
|
||||||
FieldCacheSource other = (FieldCacheSource) o;
|
FieldCacheSource other = (FieldCacheSource) o;
|
||||||
return
|
return
|
||||||
this.cache == other.cache &&
|
|
||||||
this.field.equals(other.field) &&
|
this.field.equals(other.field) &&
|
||||||
cachedFieldSourceEquals(other);
|
cachedFieldSourceEquals(other);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +83,6 @@ public abstract class FieldCacheSource extends ValueSource {
|
||||||
/*(non-Javadoc) @see java.lang.Object#hashCode() */
|
/*(non-Javadoc) @see java.lang.Object#hashCode() */
|
||||||
public final int hashCode() {
|
public final int hashCode() {
|
||||||
return
|
return
|
||||||
cache.hashCode() +
|
|
||||||
field.hashCode() +
|
field.hashCode() +
|
||||||
cachedFieldSourceHashCode();
|
cachedFieldSourceHashCode();
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,12 +62,12 @@ public class ValueSourceQuery extends Query {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ValueSourceWeight implements Weight {
|
private class ValueSourceWeight implements Weight {
|
||||||
Searcher searcher;
|
Similarity similarity;
|
||||||
float queryNorm;
|
float queryNorm;
|
||||||
float queryWeight;
|
float queryWeight;
|
||||||
|
|
||||||
public ValueSourceWeight(Searcher searcher) {
|
public ValueSourceWeight(Searcher searcher) {
|
||||||
this.searcher = searcher;
|
this.similarity = getSimilarity(searcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*(non-Javadoc) @see org.apache.lucene.search.Weight#getQuery() */
|
/*(non-Javadoc) @see org.apache.lucene.search.Weight#getQuery() */
|
||||||
|
@ -94,7 +94,7 @@ public class ValueSourceQuery extends Query {
|
||||||
|
|
||||||
/*(non-Javadoc) @see org.apache.lucene.search.Weight#scorer(org.apache.lucene.index.IndexReader) */
|
/*(non-Javadoc) @see org.apache.lucene.search.Weight#scorer(org.apache.lucene.index.IndexReader) */
|
||||||
public Scorer scorer(IndexReader reader) throws IOException {
|
public Scorer scorer(IndexReader reader) throws IOException {
|
||||||
return new ValueSourceScorer(getSimilarity(searcher), reader, this);
|
return new ValueSourceScorer(similarity, reader, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */
|
/*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */
|
||||||
|
|
|
@ -2,7 +2,11 @@ package org.apache.lucene.search;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright 2005 Apache Software Foundation
|
* Copyright 2005 Apache Software Foundation
|
||||||
|
@ -86,12 +90,38 @@ public class QueryUtils {
|
||||||
checkSkipTo(q1,is);
|
checkSkipTo(q1,is);
|
||||||
}
|
}
|
||||||
checkExplanations(q1,s);
|
checkExplanations(q1,s);
|
||||||
|
checkSerialization(q1,s);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** check that the query weight is serializable.
|
||||||
|
* @throws IOException if serialization check fail.
|
||||||
|
*/
|
||||||
|
private static void checkSerialization(Query q, Searcher s) throws IOException {
|
||||||
|
Weight w = q.weight(s);
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
ObjectOutputStream oos = new ObjectOutputStream(bos);
|
||||||
|
oos.writeObject(w);
|
||||||
|
oos.close();
|
||||||
|
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
|
||||||
|
Weight w2 = (Weight) ois.readObject();
|
||||||
|
ois.close();
|
||||||
|
|
||||||
|
//skip rquals() test for now - most weights don't overide equals() and we won't add this just for the tests.
|
||||||
|
//TestCase.assertEquals("writeObject(w) != w. ("+w+")",w2,w);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
IOException e2 = new IOException("Serialization failed for "+w);
|
||||||
|
e2.initCause(e);
|
||||||
|
throw e2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc
|
/** alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc
|
||||||
* and ensure a hitcollector receives same docs and scores
|
* and ensure a hitcollector receives same docs and scores
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,24 +19,6 @@ package org.apache.lucene.search;
|
||||||
|
|
||||||
import org.apache.lucene.search.BooleanClause.Occur;
|
import org.apache.lucene.search.BooleanClause.Occur;
|
||||||
import org.apache.lucene.search.spans.*;
|
import org.apache.lucene.search.spans.*;
|
||||||
import org.apache.lucene.store.RAMDirectory;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.IndexWriter;
|
|
||||||
import org.apache.lucene.index.IndexReader;
|
|
||||||
import org.apache.lucene.index.Term;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
|
||||||
|
|
||||||
import org.apache.lucene.document.Document;
|
|
||||||
import org.apache.lucene.document.Field;
|
|
||||||
|
|
||||||
import org.apache.lucene.queryParser.QueryParser;
|
|
||||||
import org.apache.lucene.queryParser.ParseException;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.BitSet;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TestExplanations subclass that builds up super crazy complex queries
|
* TestExplanations subclass that builds up super crazy complex queries
|
||||||
|
@ -51,11 +33,16 @@ public class TestComplexExplanations extends TestExplanations {
|
||||||
*/
|
*/
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
searcher.setSimilarity(new DefaultSimilarity() {
|
searcher.setSimilarity(createQnorm1Similarity());
|
||||||
|
}
|
||||||
|
|
||||||
|
// must be static for weight serialization tests
|
||||||
|
private static DefaultSimilarity createQnorm1Similarity() {
|
||||||
|
return new DefaultSimilarity() {
|
||||||
public float queryNorm(float sumOfSquaredWeights) {
|
public float queryNorm(float sumOfSquaredWeights) {
|
||||||
return 1.0f; // / (float) Math.sqrt(1.0f + sumOfSquaredWeights);
|
return 1.0f; // / (float) Math.sqrt(1.0f + sumOfSquaredWeights);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ package org.apache.lucene.search;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
|
@ -26,6 +25,8 @@ import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.search.BooleanClause.Occur;
|
import org.apache.lucene.search.BooleanClause.Occur;
|
||||||
import org.apache.lucene.store.RAMDirectory;
|
import org.apache.lucene.store.RAMDirectory;
|
||||||
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
|
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +39,7 @@ import java.util.BitSet;
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public class TestFilteredQuery
|
public class TestFilteredQuery
|
||||||
extends TestCase {
|
extends LuceneTestCase {
|
||||||
|
|
||||||
private IndexSearcher searcher;
|
private IndexSearcher searcher;
|
||||||
private RAMDirectory directory;
|
private RAMDirectory directory;
|
||||||
|
@ -75,7 +76,12 @@ extends TestCase {
|
||||||
|
|
||||||
searcher = new IndexSearcher (directory);
|
searcher = new IndexSearcher (directory);
|
||||||
query = new TermQuery (new Term ("field", "three"));
|
query = new TermQuery (new Term ("field", "three"));
|
||||||
filter = new Filter() {
|
filter = newStaticFilterB();
|
||||||
|
}
|
||||||
|
|
||||||
|
// must be static for serialization tests
|
||||||
|
private static Filter newStaticFilterB() {
|
||||||
|
return new Filter() {
|
||||||
public BitSet bits (IndexReader reader) {
|
public BitSet bits (IndexReader reader) {
|
||||||
BitSet bitset = new BitSet(5);
|
BitSet bitset = new BitSet(5);
|
||||||
bitset.set (1);
|
bitset.set (1);
|
||||||
|
@ -120,13 +126,7 @@ extends TestCase {
|
||||||
QueryUtils.check(filteredquery,searcher);
|
QueryUtils.check(filteredquery,searcher);
|
||||||
|
|
||||||
// test boost
|
// test boost
|
||||||
Filter f = new Filter() {
|
Filter f = newStaticFilterA();
|
||||||
public BitSet bits (IndexReader reader) {
|
|
||||||
BitSet bitset = new BitSet(5);
|
|
||||||
bitset.set(0, 5);
|
|
||||||
return bitset;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
float boost = 2.5f;
|
float boost = 2.5f;
|
||||||
BooleanQuery bq1 = new BooleanQuery();
|
BooleanQuery bq1 = new BooleanQuery();
|
||||||
|
@ -147,6 +147,17 @@ extends TestCase {
|
||||||
assertEquals(1.0f, tq.getBoost(), 0); // the boost value of the underlying query shouldn't have changed
|
assertEquals(1.0f, tq.getBoost(), 0); // the boost value of the underlying query shouldn't have changed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// must be static for serialization tests
|
||||||
|
private static Filter newStaticFilterA() {
|
||||||
|
return new Filter() {
|
||||||
|
public BitSet bits (IndexReader reader) {
|
||||||
|
BitSet bitset = new BitSet(5);
|
||||||
|
bitset.set(0, 5);
|
||||||
|
return bitset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests whether the scores of the two queries are the same.
|
* Tests whether the scores of the two queries are the same.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -192,7 +192,8 @@ public class TestBoostingTermQuery extends LuceneTestCase {
|
||||||
CheckHits.checkHitCollector(query, "noPayLoad", searcher, results);
|
CheckHits.checkHitCollector(query, "noPayLoad", searcher, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
class BoostingSimilarity extends DefaultSimilarity {
|
// must be static for weight serialization tests
|
||||||
|
static class BoostingSimilarity extends DefaultSimilarity {
|
||||||
|
|
||||||
// TODO: Remove warning after API has been finalized
|
// TODO: Remove warning after API has been finalized
|
||||||
public float scorePayload(byte[] payload, int offset, int length) {
|
public float scorePayload(byte[] payload, int offset, int length) {
|
||||||
|
|
Loading…
Reference in New Issue