LUCENE-7481: fix rewrite methods

LUCENE-7808: fix .equals/.hashCode methods
This commit is contained in:
Erik Hatcher 2017-04-27 15:43:17 -04:00
commit 64caf176ba
5 changed files with 118 additions and 10 deletions

View File

@ -100,6 +100,12 @@ Bug Fixes
* LUCENE-7797: The static FSDirectory.listAll(Path) method was always
returning an empty array. (Atkins Chang via Mike McCandless)
* LUCENE-7481: Fixed missing rewrite methods for SpanPayloadCheckQuery
and PayloadScoreQuery. (Erik Hatcher)
* LUCENE-7808: Fixed PayloadScoreQuery and SpanPayloadCheckQuery
.equals and .hashCode methods. (Erik Hatcher)
Improvements
* LUCENE-7782: OfflineSorter now passes the total number of items it

View File

@ -21,12 +21,14 @@ import java.util.Map;
import java.util.Set;
import java.util.Objects;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.similarities.ClassicSimilarity;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.search.similarities.Similarity.SimScorer;
@ -80,9 +82,19 @@ public class PayloadScoreQuery extends SpanQuery {
return wrappedQuery.getField();
}
@Override
public Query rewrite(IndexReader reader) throws IOException {
Query matchRewritten = wrappedQuery.rewrite(reader);
if (wrappedQuery != matchRewritten && matchRewritten instanceof SpanQuery) {
return new PayloadScoreQuery((SpanQuery)matchRewritten, function, includeSpanScore);
}
return super.rewrite(reader);
}
@Override
public String toString(String field) {
return "PayloadSpanQuery[" + wrappedQuery.toString(field) + "; " + function.toString() + "]";
return "PayloadScoreQuery[" + wrappedQuery.toString(field) + "; " + function.getClass().getSimpleName() + "; " + includeSpanScore + "]";
}
@Override
@ -101,7 +113,7 @@ public class PayloadScoreQuery extends SpanQuery {
private boolean equalsTo(PayloadScoreQuery other) {
return wrappedQuery.equals(other.wrappedQuery) &&
function.equals(other.function);
function.equals(other.function) && (includeSpanScore == other.includeSpanScore);
}
@Override
@ -109,6 +121,7 @@ public class PayloadScoreQuery extends SpanQuery {
int result = classHash();
result = 31 * result + Objects.hashCode(wrappedQuery);
result = 31 * result + Objects.hashCode(function);
result = 31 * result + Objects.hashCode(includeSpanScore);
return result;
}
@ -132,7 +145,7 @@ public class PayloadScoreQuery extends SpanQuery {
}
@Override
public PayloadSpanScorer scorer(LeafReaderContext context) throws IOException {
public SpanScorer scorer(LeafReaderContext context) throws IOException {
Spans spans = getSpans(context, Postings.PAYLOADS);
if (spans == null)
return null;
@ -148,7 +161,7 @@ public class PayloadScoreQuery extends SpanQuery {
@Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
PayloadSpanScorer scorer = scorer(context);
PayloadSpanScorer scorer = (PayloadSpanScorer)scorer(context);
if (scorer == null || scorer.iterator().advance(doc) != doc)
return Explanation.noMatch("No match");

View File

@ -18,14 +18,17 @@ package org.apache.lucene.queries.payloads;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext;
import org.apache.lucene.index.Terms;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.search.spans.FilterSpans;
import org.apache.lucene.search.spans.FilterSpans.AcceptStatus;
@ -64,6 +67,15 @@ public class SpanPayloadCheckQuery extends SpanQuery {
return new SpanPayloadCheckWeight(searcher, needsScores ? getTermContexts(matchWeight) : null, matchWeight, boost);
}
@Override
public Query rewrite(IndexReader reader) throws IOException {
Query matchRewritten = match.rewrite(reader);
if (match != matchRewritten && matchRewritten instanceof SpanQuery) {
return new SpanPayloadCheckQuery((SpanQuery)matchRewritten, payloadToMatch);
}
return super.rewrite(reader);
}
/**
* Weight that pulls its Spans using a PayloadSpanCollector
*/
@ -175,11 +187,15 @@ public class SpanPayloadCheckQuery extends SpanQuery {
@Override
public boolean equals(Object other) {
return sameClassAs(other) &&
payloadToMatch.equals(((SpanPayloadCheckQuery) other).payloadToMatch);
payloadToMatch.equals(((SpanPayloadCheckQuery) other).payloadToMatch) &&
match.equals(((SpanPayloadCheckQuery) other).match);
}
@Override
public int hashCode() {
return classHash() ^ payloadToMatch.hashCode();
int result = classHash();
result = 31 * result + Objects.hashCode(match);
result = 31 * result + Objects.hashCode(payloadToMatch);
return result;
}
}

View File

@ -34,6 +34,8 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.search.CheckHits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanPositionRangeQuery;
import org.apache.lucene.search.spans.SpanQuery;
@ -186,6 +188,45 @@ public class TestPayloadCheckQuery extends LuceneTestCase {
payloads.add(pay4);
query = new SpanPayloadCheckQuery(oneThousHunThree, payloads);
checkHits(query, new int[]{1103, 1203,1303,1403,1503,1603,1703,1803,1903});
}
}
public void testEquality() {
SpanQuery sq1 = new SpanTermQuery(new Term("field", "one"));
SpanQuery sq2 = new SpanTermQuery(new Term("field", "two"));
BytesRef payload1 = new BytesRef("pay1");
BytesRef payload2 = new BytesRef("pay2");
SpanQuery query1 = new SpanPayloadCheckQuery(sq1, Collections.singletonList(payload1));
SpanQuery query2 = new SpanPayloadCheckQuery(sq2, Collections.singletonList(payload1));
SpanQuery query3 = new SpanPayloadCheckQuery(sq1, Collections.singletonList(payload2));
SpanQuery query4 = new SpanPayloadCheckQuery(sq2, Collections.singletonList(payload2));
SpanQuery query5 = new SpanPayloadCheckQuery(sq1, Collections.singletonList(payload1));
assertEquals(query1, query5);
assertFalse(query1.equals(query2));
assertFalse(query1.equals(query3));
assertFalse(query1.equals(query4));
assertFalse(query2.equals(query3));
assertFalse(query2.equals(query4));
assertFalse(query3.equals(query4));
}
public void testRewrite() throws IOException {
SpanMultiTermQueryWrapper fiv = new SpanMultiTermQueryWrapper(new WildcardQuery(new Term("field", "fiv*")));
SpanMultiTermQueryWrapper hund = new SpanMultiTermQueryWrapper(new WildcardQuery(new Term("field", "hund*")));
SpanMultiTermQueryWrapper twent = new SpanMultiTermQueryWrapper(new WildcardQuery(new Term("field", "twent*")));
SpanMultiTermQueryWrapper nin = new SpanMultiTermQueryWrapper(new WildcardQuery(new Term("field", "nin*")));
SpanNearQuery sq = new SpanNearQuery(new SpanQuery[] {fiv, hund, twent, nin}, 0, true);
List<BytesRef> payloads = new ArrayList<>();
payloads.add(new BytesRef("pos: 0"));
payloads.add(new BytesRef("pos: 1"));
payloads.add(new BytesRef("pos: 2"));
payloads.add(new BytesRef("pos: 3"));
SpanPayloadCheckQuery query = new SpanPayloadCheckQuery(sq, payloads);
// if query wasn't rewritten properly, the query would have failed with "Rewrite first!"
checkHits(query, new int[]{529});
}
}

View File

@ -37,8 +37,10 @@ import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.QueryUtils;
import org.apache.lucene.search.TermStatistics;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.similarities.ClassicSimilarity;
import org.apache.lucene.search.spans.SpanContainingQuery;
import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanOrQuery;
import org.apache.lucene.search.spans.SpanQuery;
@ -172,10 +174,40 @@ public class TestPayloadScoreQuery extends LuceneTestCase {
}
@Test
public void testEquality() {
SpanQuery sq1 = new SpanTermQuery(new Term("field", "one"));
SpanQuery sq2 = new SpanTermQuery(new Term("field", "two"));
PayloadFunction minFunc = new MinPayloadFunction();
PayloadFunction maxFunc = new MaxPayloadFunction();
PayloadScoreQuery query1 = new PayloadScoreQuery(sq1, minFunc, true);
PayloadScoreQuery query2 = new PayloadScoreQuery(sq2, minFunc, true);
PayloadScoreQuery query3 = new PayloadScoreQuery(sq2, maxFunc, true);
PayloadScoreQuery query4 = new PayloadScoreQuery(sq2, maxFunc, false);
PayloadScoreQuery query5 = new PayloadScoreQuery(sq1, minFunc);
assertEquals(query1, query5);
assertFalse(query1.equals(query2));
assertFalse(query1.equals(query3));
assertFalse(query1.equals(query4));
assertFalse(query2.equals(query3));
assertFalse(query2.equals(query4));
assertFalse(query3.equals(query4));
}
public void testRewrite() throws IOException {
SpanMultiTermQueryWrapper xyz = new SpanMultiTermQueryWrapper(new WildcardQuery(new Term("field", "xyz*")));
PayloadScoreQuery psq = new PayloadScoreQuery(xyz, new AveragePayloadFunction(), false);
// if query wasn't rewritten properly, the query would have failed with "Rewrite first!"
searcher.search(psq, 1);
}
private static IndexSearcher searcher;
private static IndexReader reader;
private static Directory directory;
private static BoostingSimilarity similarity = new BoostingSimilarity();
private static JustScorePayloadSimilarity similarity = new JustScorePayloadSimilarity();
private static byte[] payload2 = new byte[]{2};
private static byte[] payload4 = new byte[]{4};
@ -260,7 +292,7 @@ public class TestPayloadScoreQuery extends LuceneTestCase {
}
static class BoostingSimilarity extends MultiplyingSimilarity {
static class JustScorePayloadSimilarity extends MultiplyingSimilarity {
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//Make everything else 1 so we see the effect of the payload