mirror of https://github.com/apache/lucene.git
LUCENE-1827: Make the payload span queries consistent
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@806894 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
fd424ef0fc
commit
9712dbe0ea
|
@ -691,12 +691,12 @@ New features
|
||||||
SpanNearQuery that does not need to use the payloads, you can
|
SpanNearQuery that does not need to use the payloads, you can
|
||||||
disable loading them with a new constructor switch. (Mark Miller)
|
disable loading them with a new constructor switch. (Mark Miller)
|
||||||
|
|
||||||
33. LUCENE-1341: Added BoostingNearQuery to enable SpanNearQuery functionality
|
33. LUCENE-1341: Added PayloadNearQuery to enable SpanNearQuery functionality
|
||||||
with payloads (Peter Keegan, Grant Ingersoll, Mark Miller)
|
with payloads (Peter Keegan, Grant Ingersoll, Mark Miller)
|
||||||
|
|
||||||
34. LUCENE-1790: Added BoostingFunctionTermQuery to enable scoring of payloads
|
34. LUCENE-1790: Added PayloadTermQuery to enable scoring of payloads
|
||||||
based on the maximum payload seen for a document.
|
based on the maximum payload seen for a document.
|
||||||
Slight refactoring of Similarity and other payload queries (Grant Ingersoll)
|
Slight refactoring of Similarity and other payload queries (Grant Ingersoll, Mark Miller)
|
||||||
|
|
||||||
36. LUCENE-1749: Addition of FieldCacheSanityChecker utility, and
|
36. LUCENE-1749: Addition of FieldCacheSanityChecker utility, and
|
||||||
hooks to use it in all existing Lucene Tests. This class can
|
hooks to use it in all existing Lucene Tests. This class can
|
||||||
|
|
|
@ -37,9 +37,9 @@ import org.apache.lucene.search.spans.TermSpans;
|
||||||
*
|
*
|
||||||
* @see org.apache.lucene.search.Similarity#scorePayload(String, byte[], int, int)
|
* @see org.apache.lucene.search.Similarity#scorePayload(String, byte[], int, int)
|
||||||
*
|
*
|
||||||
* @deprecated See {@link org.apache.lucene.search.payloads.BoostingFunctionTermQuery}
|
* @deprecated See {@link org.apache.lucene.search.payloads.PayloadTermQuery}
|
||||||
*/
|
*/
|
||||||
public class BoostingTermQuery extends BoostingFunctionTermQuery implements PayloadQuery{
|
public class BoostingTermQuery extends PayloadTermQuery {
|
||||||
|
|
||||||
public BoostingTermQuery(Term term) {
|
public BoostingTermQuery(Term term) {
|
||||||
this(term, true);
|
this(term, true);
|
||||||
|
@ -53,14 +53,14 @@ public class BoostingTermQuery extends BoostingFunctionTermQuery implements Payl
|
||||||
return new BoostingTermWeight(this, searcher);
|
return new BoostingTermWeight(this, searcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class BoostingTermWeight extends BoostingFunctionTermWeight {
|
protected class BoostingTermWeight extends PayloadTermWeight {
|
||||||
|
|
||||||
public BoostingTermWeight(BoostingTermQuery query, Searcher searcher) throws IOException {
|
public BoostingTermWeight(BoostingTermQuery query, Searcher searcher) throws IOException {
|
||||||
super(query, searcher);
|
super(query, searcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException {
|
public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException {
|
||||||
return new BoostingFunctionSpanScorer((TermSpans) query.getSpans(reader), this,
|
return new PayloadTermSpanScorer((TermSpans) query.getSpans(reader), this,
|
||||||
similarity, reader.norms(query.getField()));
|
similarity, reader.norms(query.getField()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,10 @@ import java.io.Serializable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract class that defines a way for Boosting*Query instances
|
* An abstract class that defines a way for Payload*Query instances
|
||||||
* to transform the cumulative effects of payload scores for a document.
|
* to transform the cumulative effects of payload scores for a document.
|
||||||
*
|
*
|
||||||
* @see org.apache.lucene.search.payloads.BoostingFunctionTermQuery for more information
|
* @see org.apache.lucene.search.payloads.PayloadTermQuery for more information
|
||||||
*
|
*
|
||||||
* <p/>
|
* <p/>
|
||||||
* This class and its derivations are experimental and subject to change
|
* This class and its derivations are experimental and subject to change
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
package org.apache.lucene.search.payloads;
|
package org.apache.lucene.search.payloads;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -36,35 +37,37 @@ import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is very similar to {@link org.apache.lucene.search.spans.SpanNearQuery} except
|
* This class is very similar to
|
||||||
* that it factors in the value of the payloads located at each of the positions where the
|
* {@link org.apache.lucene.search.spans.SpanNearQuery} except that it factors
|
||||||
|
* in the value of the payloads located at each of the positions where the
|
||||||
* {@link org.apache.lucene.search.spans.TermSpans} occurs.
|
* {@link org.apache.lucene.search.spans.TermSpans} occurs.
|
||||||
* <p/>
|
* <p/>
|
||||||
* In order to take advantage of this, you must override {@link org.apache.lucene.search.Similarity#scorePayload(String, byte[],int,int)}
|
* In order to take advantage of this, you must override
|
||||||
|
* {@link org.apache.lucene.search.Similarity#scorePayload(String, byte[],int,int)}
|
||||||
* which returns 1 by default.
|
* which returns 1 by default.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Payload scores are aggregated using a pluggable {@link PayloadFunction}.
|
* Payload scores are aggregated using a pluggable {@link PayloadFunction}.
|
||||||
*
|
*
|
||||||
* @see org.apache.lucene.search.Similarity#scorePayload(String, byte[], int, int)
|
* @see org.apache.lucene.search.Similarity#scorePayload(String, byte[], int,
|
||||||
|
* int)
|
||||||
*/
|
*/
|
||||||
|
public class PayloadNearQuery extends SpanNearQuery {
|
||||||
public class BoostingNearQuery extends SpanNearQuery implements PayloadQuery {
|
|
||||||
protected String fieldName;
|
protected String fieldName;
|
||||||
protected PayloadFunction function;
|
protected PayloadFunction function;
|
||||||
|
|
||||||
public BoostingNearQuery(SpanQuery[] clauses, int slop, boolean inOrder) {
|
public PayloadNearQuery(SpanQuery[] clauses, int slop, boolean inOrder) {
|
||||||
this(clauses, slop, inOrder, new AveragePayloadFunction());
|
this(clauses, slop, inOrder, new AveragePayloadFunction());
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoostingNearQuery(SpanQuery[] clauses, int slop, boolean inOrder, PayloadFunction function) {
|
public PayloadNearQuery(SpanQuery[] clauses, int slop, boolean inOrder,
|
||||||
|
PayloadFunction function) {
|
||||||
super(clauses, slop, inOrder);
|
super(clauses, slop, inOrder);
|
||||||
fieldName = clauses[0].getField(); // all clauses must have same field
|
fieldName = clauses[0].getField(); // all clauses must have same field
|
||||||
this.function = function;
|
this.function = function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Weight createWeight(Searcher searcher) throws IOException {
|
public Weight createWeight(Searcher searcher) throws IOException {
|
||||||
return new BoostingSpanWeight(this, searcher);
|
return new PayloadNearSpanWeight(this, searcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object clone() {
|
public Object clone() {
|
||||||
|
@ -75,17 +78,18 @@ public class BoostingNearQuery extends SpanNearQuery implements PayloadQuery {
|
||||||
SpanQuery clause = (SpanQuery) clauses.get(i);
|
SpanQuery clause = (SpanQuery) clauses.get(i);
|
||||||
newClauses[i] = (SpanQuery) clause.clone();
|
newClauses[i] = (SpanQuery) clause.clone();
|
||||||
}
|
}
|
||||||
BoostingNearQuery boostingNearQuery = new BoostingNearQuery(newClauses, slop, inOrder);
|
PayloadNearQuery boostingNearQuery = new PayloadNearQuery(newClauses, slop,
|
||||||
|
inOrder);
|
||||||
boostingNearQuery.setBoost(getBoost());
|
boostingNearQuery.setBoost(getBoost());
|
||||||
return boostingNearQuery;
|
return boostingNearQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString(String field) {
|
public String toString(String field) {
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
buffer.append("boostingNear([");
|
buffer.append("payloadNear([");
|
||||||
Iterator i = clauses.iterator();
|
Iterator i = clauses.iterator();
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
SpanQuery clause = (SpanQuery)i.next();
|
SpanQuery clause = (SpanQuery) i.next();
|
||||||
buffer.append(clause.toString(field));
|
buffer.append(clause.toString(field));
|
||||||
if (i.hasNext()) {
|
if (i.hasNext()) {
|
||||||
buffer.append(", ");
|
buffer.append(", ");
|
||||||
|
@ -100,7 +104,7 @@ public class BoostingNearQuery extends SpanNearQuery implements PayloadQuery {
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Override
|
// @Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = super.hashCode();
|
int result = super.hashCode();
|
||||||
|
@ -109,7 +113,7 @@ public class BoostingNearQuery extends SpanNearQuery implements PayloadQuery {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Override
|
// @Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
return true;
|
return true;
|
||||||
|
@ -117,7 +121,7 @@ public class BoostingNearQuery extends SpanNearQuery implements PayloadQuery {
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
if (getClass() != obj.getClass())
|
||||||
return false;
|
return false;
|
||||||
BoostingNearQuery other = (BoostingNearQuery) obj;
|
PayloadNearQuery other = (PayloadNearQuery) obj;
|
||||||
if (fieldName == null) {
|
if (fieldName == null) {
|
||||||
if (other.fieldName != null)
|
if (other.fieldName != null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -131,33 +135,33 @@ public class BoostingNearQuery extends SpanNearQuery implements PayloadQuery {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BoostingSpanWeight extends SpanWeight {
|
public class PayloadNearSpanWeight extends SpanWeight {
|
||||||
public BoostingSpanWeight(SpanQuery query, Searcher searcher) throws IOException {
|
public PayloadNearSpanWeight(SpanQuery query, Searcher searcher)
|
||||||
|
throws IOException {
|
||||||
super(query, searcher);
|
super(query, searcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Scorer scorer(IndexReader reader) throws IOException {
|
public Scorer scorer(IndexReader reader) throws IOException {
|
||||||
return new BoostingSpanScorer(query.getSpans(reader), this,
|
return new PayloadNearSpanScorer(query.getSpans(reader), this,
|
||||||
similarity,
|
similarity, reader.norms(query.getField()));
|
||||||
reader.norms(query.getField()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException {
|
public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder,
|
||||||
return new BoostingSpanScorer(query.getSpans(reader), this,
|
boolean topScorer) throws IOException {
|
||||||
similarity,
|
return new PayloadNearSpanScorer(query.getSpans(reader), this,
|
||||||
reader.norms(query.getField()));
|
similarity, reader.norms(query.getField()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BoostingSpanScorer extends SpanScorer {
|
public class PayloadNearSpanScorer extends SpanScorer {
|
||||||
Spans spans;
|
Spans spans;
|
||||||
|
|
||||||
protected float payloadScore;
|
protected float payloadScore;
|
||||||
private int payloadsSeen;
|
private int payloadsSeen;
|
||||||
Similarity similarity = getSimilarity();
|
Similarity similarity = getSimilarity();
|
||||||
|
|
||||||
protected BoostingSpanScorer(Spans spans, Weight weight, Similarity similarity, byte[] norms)
|
protected PayloadNearSpanScorer(Spans spans, Weight weight,
|
||||||
throws IOException {
|
Similarity similarity, byte[] norms) throws IOException {
|
||||||
super(spans, weight, similarity, norms);
|
super(spans, weight, similarity, norms);
|
||||||
this.spans = spans;
|
this.spans = spans;
|
||||||
}
|
}
|
||||||
|
@ -167,12 +171,14 @@ public class BoostingNearQuery extends SpanNearQuery implements PayloadQuery {
|
||||||
for (int i = 0; i < subSpans.length; i++) {
|
for (int i = 0; i < subSpans.length; i++) {
|
||||||
if (subSpans[i] instanceof NearSpansOrdered) {
|
if (subSpans[i] instanceof NearSpansOrdered) {
|
||||||
if (((NearSpansOrdered) subSpans[i]).isPayloadAvailable()) {
|
if (((NearSpansOrdered) subSpans[i]).isPayloadAvailable()) {
|
||||||
processPayloads(((NearSpansOrdered) subSpans[i]).getPayload(), subSpans[i].start(), subSpans[i].end());
|
processPayloads(((NearSpansOrdered) subSpans[i]).getPayload(),
|
||||||
|
subSpans[i].start(), subSpans[i].end());
|
||||||
}
|
}
|
||||||
getPayloads(((NearSpansOrdered) subSpans[i]).getSubSpans());
|
getPayloads(((NearSpansOrdered) subSpans[i]).getSubSpans());
|
||||||
} else if (subSpans[i] instanceof NearSpansUnordered) {
|
} else if (subSpans[i] instanceof NearSpansUnordered) {
|
||||||
if (((NearSpansUnordered) subSpans[i]).isPayloadAvailable()) {
|
if (((NearSpansUnordered) subSpans[i]).isPayloadAvailable()) {
|
||||||
processPayloads(((NearSpansUnordered) subSpans[i]).getPayload(), subSpans[i].start(), subSpans[i].end());
|
processPayloads(((NearSpansUnordered) subSpans[i]).getPayload(),
|
||||||
|
subSpans[i].start(), subSpans[i].end());
|
||||||
}
|
}
|
||||||
getPayloads(((NearSpansUnordered) subSpans[i]).getSubSpans());
|
getPayloads(((NearSpansUnordered) subSpans[i]).getSubSpans());
|
||||||
}
|
}
|
||||||
|
@ -180,7 +186,8 @@ public class BoostingNearQuery extends SpanNearQuery implements PayloadQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* By default, uses the {@link PayloadFunction} to score the payloads, but can be overridden to do other things.
|
* By default, uses the {@link PayloadFunction} to score the payloads, but
|
||||||
|
* can be overridden to do other things.
|
||||||
*
|
*
|
||||||
* @param payLoads The payloads
|
* @param payLoads The payloads
|
||||||
* @param start The start position of the span being scored
|
* @param start The start position of the span being scored
|
||||||
|
@ -191,8 +198,9 @@ public class BoostingNearQuery extends SpanNearQuery implements PayloadQuery {
|
||||||
protected void processPayloads(Collection payLoads, int start, int end) {
|
protected void processPayloads(Collection payLoads, int start, int end) {
|
||||||
for (Iterator iterator = payLoads.iterator(); iterator.hasNext();) {
|
for (Iterator iterator = payLoads.iterator(); iterator.hasNext();) {
|
||||||
byte[] thePayload = (byte[]) iterator.next();
|
byte[] thePayload = (byte[]) iterator.next();
|
||||||
payloadScore = function.currentScore(doc, fieldName, start, end, payloadsSeen, payloadScore,
|
payloadScore = function.currentScore(doc, fieldName, start, end,
|
||||||
similarity.scorePayload(doc, fieldName, spans.start(), spans.end(), thePayload, 0, thePayload.length));
|
payloadsSeen, payloadScore, similarity.scorePayload(doc, fieldName,
|
||||||
|
spans.start(), spans.end(), thePayload, 0, thePayload.length));
|
||||||
++payloadsSeen;
|
++payloadsSeen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +217,8 @@ public class BoostingNearQuery extends SpanNearQuery implements PayloadQuery {
|
||||||
|
|
||||||
public float score() throws IOException {
|
public float score() throws IOException {
|
||||||
|
|
||||||
return super.score() * function.docScore(doc, fieldName, payloadsSeen, payloadScore);
|
return super.score()
|
||||||
|
* function.docScore(doc, fieldName, payloadsSeen, payloadScore);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Explanation explain(int doc) throws IOException {
|
public Explanation explain(int doc) throws IOException {
|
||||||
|
@ -218,7 +227,8 @@ public class BoostingNearQuery extends SpanNearQuery implements PayloadQuery {
|
||||||
result.addDetail(nonPayloadExpl);
|
result.addDetail(nonPayloadExpl);
|
||||||
Explanation payloadBoost = new Explanation();
|
Explanation payloadBoost = new Explanation();
|
||||||
result.addDetail(payloadBoost);
|
result.addDetail(payloadBoost);
|
||||||
float avgPayloadScore = (payloadsSeen > 0 ? (payloadScore / payloadsSeen) : 1);
|
float avgPayloadScore = (payloadsSeen > 0 ? (payloadScore / payloadsSeen)
|
||||||
|
: 1);
|
||||||
payloadBoost.setValue(avgPayloadScore);
|
payloadBoost.setValue(avgPayloadScore);
|
||||||
payloadBoost.setDescription("scorePayload(...)");
|
payloadBoost.setDescription("scorePayload(...)");
|
||||||
result.setValue(nonPayloadExpl.getValue() * avgPayloadScore);
|
result.setValue(nonPayloadExpl.getValue() * avgPayloadScore);
|
|
@ -1,24 +0,0 @@
|
||||||
package org.apache.lucene.search.payloads;
|
|
||||||
/**
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marker interface indicating this Query is Payload aware.
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
public interface PayloadQuery {
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
package org.apache.lucene.search.payloads;
|
package org.apache.lucene.search.payloads;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -33,9 +34,10 @@ import org.apache.lucene.search.spans.SpanScorer;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is very similar to {@link org.apache.lucene.search.spans.SpanTermQuery}
|
* This class is very similar to
|
||||||
* except that it factors in the value of the payload located at each of the positions
|
* {@link org.apache.lucene.search.spans.SpanTermQuery} except that it factors
|
||||||
* where the {@link org.apache.lucene.index.Term} occurs.
|
* in the value of the payload located at each of the positions where the
|
||||||
|
* {@link org.apache.lucene.index.Term} occurs.
|
||||||
* <p>
|
* <p>
|
||||||
* In order to take advantage of this, you must override
|
* In order to take advantage of this, you must override
|
||||||
* {@link org.apache.lucene.search.Similarity#scorePayload(String, byte[],int,int)}
|
* {@link org.apache.lucene.search.Similarity#scorePayload(String, byte[],int,int)}
|
||||||
|
@ -43,46 +45,47 @@ import java.io.IOException;
|
||||||
* <p>
|
* <p>
|
||||||
* Payload scores are aggregated using a pluggable {@link PayloadFunction}.
|
* Payload scores are aggregated using a pluggable {@link PayloadFunction}.
|
||||||
**/
|
**/
|
||||||
public class BoostingFunctionTermQuery extends SpanTermQuery implements PayloadQuery{
|
public class PayloadTermQuery extends SpanTermQuery {
|
||||||
protected PayloadFunction function;
|
protected PayloadFunction function;
|
||||||
private boolean includeSpanScore;
|
private boolean includeSpanScore;
|
||||||
|
|
||||||
public BoostingFunctionTermQuery(Term term, PayloadFunction function) {
|
public PayloadTermQuery(Term term, PayloadFunction function) {
|
||||||
this(term, function, true);
|
this(term, function, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoostingFunctionTermQuery(Term term, PayloadFunction function, boolean includeSpanScore) {
|
public PayloadTermQuery(Term term, PayloadFunction function,
|
||||||
|
boolean includeSpanScore) {
|
||||||
super(term);
|
super(term);
|
||||||
this.function = function;
|
this.function = function;
|
||||||
this.includeSpanScore = includeSpanScore;
|
this.includeSpanScore = includeSpanScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Weight createWeight(Searcher searcher) throws IOException {
|
public Weight createWeight(Searcher searcher) throws IOException {
|
||||||
return new BoostingFunctionTermWeight(this, searcher);
|
return new PayloadTermWeight(this, searcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class BoostingFunctionTermWeight extends SpanWeight {
|
protected class PayloadTermWeight extends SpanWeight {
|
||||||
|
|
||||||
public BoostingFunctionTermWeight(BoostingFunctionTermQuery query, Searcher searcher) throws IOException {
|
public PayloadTermWeight(PayloadTermQuery query, Searcher searcher)
|
||||||
|
throws IOException {
|
||||||
super(query, searcher);
|
super(query, searcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException {
|
public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder,
|
||||||
return new BoostingFunctionSpanScorer((TermSpans) query.getSpans(reader), this,
|
boolean topScorer) throws IOException {
|
||||||
similarity, reader.norms(query.getField()));
|
return new PayloadTermSpanScorer((TermSpans) query.getSpans(reader),
|
||||||
|
this, similarity, reader.norms(query.getField()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class BoostingFunctionSpanScorer extends SpanScorer {
|
protected class PayloadTermSpanScorer extends SpanScorer {
|
||||||
//TODO: is this the best way to allocate this?
|
// TODO: is this the best way to allocate this?
|
||||||
protected byte[] payload = new byte[256];
|
protected byte[] payload = new byte[256];
|
||||||
protected TermPositions positions;
|
protected TermPositions positions;
|
||||||
protected float payloadScore;
|
protected float payloadScore;
|
||||||
protected int payloadsSeen;
|
protected int payloadsSeen;
|
||||||
|
|
||||||
public BoostingFunctionSpanScorer(TermSpans spans, Weight weight, Similarity similarity,
|
public PayloadTermSpanScorer(TermSpans spans, Weight weight,
|
||||||
byte[] norms) throws IOException {
|
Similarity similarity, byte[] norms) throws IOException {
|
||||||
super(spans, weight, similarity, norms);
|
super(spans, weight, similarity, norms);
|
||||||
positions = spans.getPositions();
|
positions = spans.getPositions();
|
||||||
}
|
}
|
||||||
|
@ -102,21 +105,23 @@ public class BoostingFunctionTermQuery extends SpanTermQuery implements Payload
|
||||||
freq += similarity1.sloppyFreq(matchLength);
|
freq += similarity1.sloppyFreq(matchLength);
|
||||||
processPayload(similarity1);
|
processPayload(similarity1);
|
||||||
|
|
||||||
more = spans.next();//this moves positions to the next match in this document
|
more = spans.next();// this moves positions to the next match in this
|
||||||
|
// document
|
||||||
}
|
}
|
||||||
return more || (freq != 0);
|
return more || (freq != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void processPayload(Similarity similarity) throws IOException {
|
protected void processPayload(Similarity similarity) throws IOException {
|
||||||
if (positions.isPayloadAvailable()) {
|
if (positions.isPayloadAvailable()) {
|
||||||
payload = positions.getPayload(payload, 0);
|
payload = positions.getPayload(payload, 0);
|
||||||
payloadScore = function.currentScore(doc, term.field(), spans.start(), spans.end(), payloadsSeen, payloadScore,
|
payloadScore = function.currentScore(doc, term.field(),
|
||||||
similarity.scorePayload(doc, term.field(), spans.start(), spans.end(), payload, 0, positions.getPayloadLength()));
|
spans.start(), spans.end(), payloadsSeen, payloadScore,
|
||||||
|
similarity.scorePayload(doc, term.field(), spans.start(), spans
|
||||||
|
.end(), payload, 0, positions.getPayloadLength()));
|
||||||
payloadsSeen++;
|
payloadsSeen++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//zero out the payload?
|
// zero out the payload?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +132,8 @@ public class BoostingFunctionTermQuery extends SpanTermQuery implements Payload
|
||||||
*/
|
*/
|
||||||
public float score() throws IOException {
|
public float score() throws IOException {
|
||||||
|
|
||||||
return includeSpanScore ? getSpanScore() * getPayloadScore() : getPayloadScore();
|
return includeSpanScore ? getSpanScore() * getPayloadScore()
|
||||||
|
: getPayloadScore();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -140,35 +146,38 @@ public class BoostingFunctionTermQuery extends SpanTermQuery implements Payload
|
||||||
*
|
*
|
||||||
* @see #score()
|
* @see #score()
|
||||||
*/
|
*/
|
||||||
protected float getSpanScore() throws IOException{
|
protected float getSpanScore() throws IOException {
|
||||||
return super.score();
|
return super.score();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The score for the payload
|
* The score for the payload
|
||||||
* @return The score, as calculated by {@link PayloadFunction#docScore(int, String, int, float)}
|
*
|
||||||
|
* @return The score, as calculated by
|
||||||
|
* {@link PayloadFunction#docScore(int, String, int, float)}
|
||||||
*/
|
*/
|
||||||
protected float getPayloadScore() {
|
protected float getPayloadScore() {
|
||||||
return function.docScore(doc, term.field(), payloadsSeen, payloadScore);
|
return function.docScore(doc, term.field(), payloadsSeen, payloadScore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Explanation explain(final int doc) throws IOException {
|
public Explanation explain(final int doc) throws IOException {
|
||||||
ComplexExplanation result = new ComplexExplanation();
|
ComplexExplanation result = new ComplexExplanation();
|
||||||
Explanation nonPayloadExpl = super.explain(doc);
|
Explanation nonPayloadExpl = super.explain(doc);
|
||||||
result.addDetail(nonPayloadExpl);
|
result.addDetail(nonPayloadExpl);
|
||||||
//QUESTION: Is there a way to avoid this skipTo call? We need to know whether to load the payload or not
|
// QUESTION: Is there a way to avoid this skipTo call? We need to know
|
||||||
|
// whether to load the payload or not
|
||||||
Explanation payloadBoost = new Explanation();
|
Explanation payloadBoost = new Explanation();
|
||||||
result.addDetail(payloadBoost);
|
result.addDetail(payloadBoost);
|
||||||
|
|
||||||
|
|
||||||
float payloadScore = getPayloadScore();
|
float payloadScore = getPayloadScore();
|
||||||
payloadBoost.setValue(payloadScore);
|
payloadBoost.setValue(payloadScore);
|
||||||
//GSI: I suppose we could toString the payload, but I don't think that would be a good idea
|
// GSI: I suppose we could toString the payload, but I don't think that
|
||||||
|
// would be a good idea
|
||||||
payloadBoost.setDescription("scorePayload(...)");
|
payloadBoost.setDescription("scorePayload(...)");
|
||||||
result.setValue(nonPayloadExpl.getValue() * payloadScore);
|
result.setValue(nonPayloadExpl.getValue() * payloadScore);
|
||||||
result.setDescription("btq, product of:");
|
result.setDescription("btq, product of:");
|
||||||
result.setMatch(nonPayloadExpl.getValue()==0 ? Boolean.FALSE : Boolean.TRUE); // LUCENE-1303
|
result.setMatch(nonPayloadExpl.getValue() == 0 ? Boolean.FALSE
|
||||||
|
: Boolean.TRUE); // LUCENE-1303
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +199,7 @@ public class BoostingFunctionTermQuery extends SpanTermQuery implements Payload
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
if (getClass() != obj.getClass())
|
||||||
return false;
|
return false;
|
||||||
BoostingFunctionTermQuery other = (BoostingFunctionTermQuery) obj;
|
PayloadTermQuery other = (PayloadTermQuery) obj;
|
||||||
if (function == null) {
|
if (function == null) {
|
||||||
if (other.function != null)
|
if (other.function != null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -201,5 +210,4 @@ public class BoostingFunctionTermQuery extends SpanTermQuery implements Payload
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,8 +26,8 @@
|
||||||
</DIV>
|
</DIV>
|
||||||
<div>
|
<div>
|
||||||
<ol>
|
<ol>
|
||||||
<li><a href="./BoostingFunctionTermQuery.html">BoostingFunctionTermQuery</a> -- Boost a term's score based on the value of the payload located at that term.</li>
|
<li><a href="./PayloadTermQuery.html">PayloadTermQuery</a> -- Boost a term's score based on the value of the payload located at that term.</li>
|
||||||
<li><a href="./BoostingNearQuery.html">BoostingNearQuery</a> -- A <a href="SpanNearQuery.html">SpanNearQuery</a> that factors in the value of the payloads located
|
<li><a href="./PayloadNearQuery.html">PayloadNearQuery</a> -- A <a href="SpanNearQuery.html">SpanNearQuery</a> that factors in the value of the payloads located
|
||||||
at each of the positions where the spans occur.</li>
|
at each of the positions where the spans occur.</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -42,13 +42,13 @@ import org.apache.lucene.util.English;
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
|
|
||||||
|
|
||||||
public class TestBoostingNearQuery extends LuceneTestCase {
|
public class TestPayloadNearQuery extends LuceneTestCase {
|
||||||
private IndexSearcher searcher;
|
private IndexSearcher searcher;
|
||||||
private BoostingSimilarity similarity = new BoostingSimilarity();
|
private BoostingSimilarity similarity = new BoostingSimilarity();
|
||||||
private byte[] payload2 = new byte[]{2};
|
private byte[] payload2 = new byte[]{2};
|
||||||
private byte[] payload4 = new byte[]{4};
|
private byte[] payload4 = new byte[]{4};
|
||||||
|
|
||||||
public TestBoostingNearQuery(String s) {
|
public TestPayloadNearQuery(String s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,14 +86,14 @@ public class TestBoostingNearQuery extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BoostingNearQuery newPhraseQuery (String fieldName, String phrase, boolean inOrder) {
|
private PayloadNearQuery newPhraseQuery (String fieldName, String phrase, boolean inOrder) {
|
||||||
int n;
|
int n;
|
||||||
String[] words = phrase.split("[\\s]+");
|
String[] words = phrase.split("[\\s]+");
|
||||||
SpanQuery clauses[] = new SpanQuery[words.length];
|
SpanQuery clauses[] = new SpanQuery[words.length];
|
||||||
for (int i=0;i<clauses.length;i++) {
|
for (int i=0;i<clauses.length;i++) {
|
||||||
clauses[i] = new BoostingTermQuery(new Term(fieldName, words[i]));
|
clauses[i] = new PayloadTermQuery(new Term(fieldName, words[i]), new AveragePayloadFunction());
|
||||||
}
|
}
|
||||||
return new BoostingNearQuery(clauses, 0, inOrder);
|
return new PayloadNearQuery(clauses, 0, inOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
|
@ -117,7 +117,7 @@ public class TestBoostingNearQuery extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void test() throws IOException {
|
public void test() throws IOException {
|
||||||
BoostingNearQuery query;
|
PayloadNearQuery query;
|
||||||
TopDocs hits;
|
TopDocs hits;
|
||||||
|
|
||||||
query = newPhraseQuery("field", "twenty two", true);
|
query = newPhraseQuery("field", "twenty two", true);
|
||||||
|
@ -149,7 +149,7 @@ public class TestBoostingNearQuery extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testLongerSpan() throws IOException {
|
public void testLongerSpan() throws IOException {
|
||||||
BoostingNearQuery query;
|
PayloadNearQuery query;
|
||||||
TopDocs hits;
|
TopDocs hits;
|
||||||
query = newPhraseQuery("field", "nine hundred ninety nine", true);
|
query = newPhraseQuery("field", "nine hundred ninety nine", true);
|
||||||
hits = searcher.search(query, null, 100);
|
hits = searcher.search(query, null, 100);
|
||||||
|
@ -163,7 +163,7 @@ public class TestBoostingNearQuery extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testComplexNested() throws IOException {
|
public void testComplexNested() throws IOException {
|
||||||
BoostingNearQuery query;
|
PayloadNearQuery query;
|
||||||
TopDocs hits;
|
TopDocs hits;
|
||||||
|
|
||||||
// combine ordered and unordered spans with some nesting to make sure all payloads are counted
|
// combine ordered and unordered spans with some nesting to make sure all payloads are counted
|
||||||
|
@ -172,8 +172,8 @@ public class TestBoostingNearQuery extends LuceneTestCase {
|
||||||
SpanQuery q2 = newPhraseQuery("field", "ninety nine", true);
|
SpanQuery q2 = newPhraseQuery("field", "ninety nine", true);
|
||||||
SpanQuery q3 = newPhraseQuery("field", "nine ninety", false);
|
SpanQuery q3 = newPhraseQuery("field", "nine ninety", false);
|
||||||
SpanQuery q4 = newPhraseQuery("field", "hundred nine", false);
|
SpanQuery q4 = newPhraseQuery("field", "hundred nine", false);
|
||||||
SpanQuery[]clauses = new SpanQuery[] {new BoostingNearQuery(new SpanQuery[] {q1,q2}, 0, true), new BoostingNearQuery(new SpanQuery[] {q3,q4}, 0, false)};
|
SpanQuery[]clauses = new SpanQuery[] {new PayloadNearQuery(new SpanQuery[] {q1,q2}, 0, true), new PayloadNearQuery(new SpanQuery[] {q3,q4}, 0, false)};
|
||||||
query = new BoostingNearQuery(clauses, 0, false);
|
query = new PayloadNearQuery(clauses, 0, false);
|
||||||
hits = searcher.search(query, null, 100);
|
hits = searcher.search(query, null, 100);
|
||||||
assertTrue("hits is null and it shouldn't be", hits != null);
|
assertTrue("hits is null and it shouldn't be", hits != null);
|
||||||
// should be only 1 hit - doc 999
|
// should be only 1 hit - doc 999
|
|
@ -49,7 +49,7 @@ import java.io.IOException;
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
public class BoostingFunctionTermQueryTest extends LuceneTestCase {
|
public class TestPayloadTermQuery extends LuceneTestCase {
|
||||||
private IndexSearcher searcher;
|
private IndexSearcher searcher;
|
||||||
private BoostingSimilarity similarity = new BoostingSimilarity();
|
private BoostingSimilarity similarity = new BoostingSimilarity();
|
||||||
private byte[] payloadField = new byte[]{1};
|
private byte[] payloadField = new byte[]{1};
|
||||||
|
@ -57,7 +57,7 @@ public class BoostingFunctionTermQueryTest extends LuceneTestCase {
|
||||||
private byte[] payloadMultiField2 = new byte[]{4};
|
private byte[] payloadMultiField2 = new byte[]{4};
|
||||||
protected RAMDirectory directory;
|
protected RAMDirectory directory;
|
||||||
|
|
||||||
public BoostingFunctionTermQueryTest(String s) {
|
public TestPayloadTermQuery(String s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ public class BoostingFunctionTermQueryTest extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void test() throws IOException {
|
public void test() throws IOException {
|
||||||
BoostingFunctionTermQuery query = new BoostingFunctionTermQuery(new Term("field", "seventy"),
|
PayloadTermQuery query = new PayloadTermQuery(new Term("field", "seventy"),
|
||||||
new MaxPayloadFunction());
|
new MaxPayloadFunction());
|
||||||
TopDocs hits = searcher.search(query, null, 100);
|
TopDocs hits = searcher.search(query, null, 100);
|
||||||
assertTrue("hits is null and it shouldn't be", hits != null);
|
assertTrue("hits is null and it shouldn't be", hits != null);
|
||||||
|
@ -155,7 +155,7 @@ public class BoostingFunctionTermQueryTest extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testQuery() {
|
public void testQuery() {
|
||||||
BoostingFunctionTermQuery boostingFuncTermQuery = new BoostingFunctionTermQuery(new Term(PayloadHelper.MULTI_FIELD, "seventy"),
|
PayloadTermQuery boostingFuncTermQuery = new PayloadTermQuery(new Term(PayloadHelper.MULTI_FIELD, "seventy"),
|
||||||
new MaxPayloadFunction());
|
new MaxPayloadFunction());
|
||||||
QueryUtils.check(boostingFuncTermQuery);
|
QueryUtils.check(boostingFuncTermQuery);
|
||||||
|
|
||||||
|
@ -163,14 +163,14 @@ public class BoostingFunctionTermQueryTest extends LuceneTestCase {
|
||||||
|
|
||||||
assertTrue(boostingFuncTermQuery.equals(spanTermQuery) == spanTermQuery.equals(boostingFuncTermQuery));
|
assertTrue(boostingFuncTermQuery.equals(spanTermQuery) == spanTermQuery.equals(boostingFuncTermQuery));
|
||||||
|
|
||||||
BoostingFunctionTermQuery boostingFuncTermQuery2 = new BoostingFunctionTermQuery(new Term(PayloadHelper.MULTI_FIELD, "seventy"),
|
PayloadTermQuery boostingFuncTermQuery2 = new PayloadTermQuery(new Term(PayloadHelper.MULTI_FIELD, "seventy"),
|
||||||
new AveragePayloadFunction());
|
new AveragePayloadFunction());
|
||||||
|
|
||||||
QueryUtils.checkUnequal(boostingFuncTermQuery, boostingFuncTermQuery2);
|
QueryUtils.checkUnequal(boostingFuncTermQuery, boostingFuncTermQuery2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMultipleMatchesPerDoc() throws Exception {
|
public void testMultipleMatchesPerDoc() throws Exception {
|
||||||
BoostingFunctionTermQuery query = new BoostingFunctionTermQuery(new Term(PayloadHelper.MULTI_FIELD, "seventy"),
|
PayloadTermQuery query = new PayloadTermQuery(new Term(PayloadHelper.MULTI_FIELD, "seventy"),
|
||||||
new MaxPayloadFunction());
|
new MaxPayloadFunction());
|
||||||
TopDocs hits = searcher.search(query, null, 100);
|
TopDocs hits = searcher.search(query, null, 100);
|
||||||
assertTrue("hits is null and it shouldn't be", hits != null);
|
assertTrue("hits is null and it shouldn't be", hits != null);
|
||||||
|
@ -209,7 +209,7 @@ public class BoostingFunctionTermQueryTest extends LuceneTestCase {
|
||||||
|
|
||||||
//Set includeSpanScore to false, in which case just the payload score comes through.
|
//Set includeSpanScore to false, in which case just the payload score comes through.
|
||||||
public void testIgnoreSpanScorer() throws Exception {
|
public void testIgnoreSpanScorer() throws Exception {
|
||||||
BoostingFunctionTermQuery query = new BoostingFunctionTermQuery(new Term(PayloadHelper.MULTI_FIELD, "seventy"),
|
PayloadTermQuery query = new PayloadTermQuery(new Term(PayloadHelper.MULTI_FIELD, "seventy"),
|
||||||
new MaxPayloadFunction(), false);
|
new MaxPayloadFunction(), false);
|
||||||
|
|
||||||
IndexSearcher theSearcher = new IndexSearcher(directory, true);
|
IndexSearcher theSearcher = new IndexSearcher(directory, true);
|
||||||
|
@ -249,7 +249,7 @@ public class BoostingFunctionTermQueryTest extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNoMatch() throws Exception {
|
public void testNoMatch() throws Exception {
|
||||||
BoostingFunctionTermQuery query = new BoostingFunctionTermQuery(new Term(PayloadHelper.FIELD, "junk"),
|
PayloadTermQuery query = new PayloadTermQuery(new Term(PayloadHelper.FIELD, "junk"),
|
||||||
new MaxPayloadFunction());
|
new MaxPayloadFunction());
|
||||||
TopDocs hits = searcher.search(query, null, 100);
|
TopDocs hits = searcher.search(query, null, 100);
|
||||||
assertTrue("hits is null and it shouldn't be", hits != null);
|
assertTrue("hits is null and it shouldn't be", hits != null);
|
||||||
|
@ -258,9 +258,9 @@ public class BoostingFunctionTermQueryTest extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNoPayload() throws Exception {
|
public void testNoPayload() throws Exception {
|
||||||
BoostingFunctionTermQuery q1 = new BoostingFunctionTermQuery(new Term(PayloadHelper.NO_PAYLOAD_FIELD, "zero"),
|
PayloadTermQuery q1 = new PayloadTermQuery(new Term(PayloadHelper.NO_PAYLOAD_FIELD, "zero"),
|
||||||
new MaxPayloadFunction());
|
new MaxPayloadFunction());
|
||||||
BoostingFunctionTermQuery q2 = new BoostingFunctionTermQuery(new Term(PayloadHelper.NO_PAYLOAD_FIELD, "foo"),
|
PayloadTermQuery q2 = new PayloadTermQuery(new Term(PayloadHelper.NO_PAYLOAD_FIELD, "foo"),
|
||||||
new MaxPayloadFunction());
|
new MaxPayloadFunction());
|
||||||
BooleanClause c1 = new BooleanClause(q1, BooleanClause.Occur.MUST);
|
BooleanClause c1 = new BooleanClause(q1, BooleanClause.Occur.MUST);
|
||||||
BooleanClause c2 = new BooleanClause(q2, BooleanClause.Occur.MUST_NOT);
|
BooleanClause c2 = new BooleanClause(q2, BooleanClause.Occur.MUST_NOT);
|
Loading…
Reference in New Issue