mirror of https://github.com/apache/lucene.git
LUCENE-7369: Similarity.coord and BooleanQuery.disableCoord are removed.
This commit is contained in:
parent
24d6b78469
commit
f1528bf338
|
@ -10,6 +10,9 @@ API Changes
|
|||
* LUCENE-2605: Classic QueryParser no longer splits on whitespace by default.
|
||||
Use setSplitOnWhitespace(true) to get the old behavior. (Steve Rowe)
|
||||
|
||||
* LUCENE-7369: Similarity.coord and BooleanQuery.disableCoord are removed.
|
||||
(Adrien Grand)
|
||||
|
||||
Bug Fixes
|
||||
|
||||
Improvements
|
||||
|
|
|
@ -18,3 +18,14 @@ classes from the java.util.zip package.
|
|||
|
||||
Clients wishing to render Explanations as HTML should implement their own
|
||||
utilities for this.
|
||||
|
||||
## Similarity.coord and BooleanQuery.disableCoord removed (LUCENE-7369)
|
||||
|
||||
Coordination factors were a workaround for the fact that the ClassicSimilarity
|
||||
does not have strong enough term frequency saturation. This causes disjunctions
|
||||
to get better scores on documents that have many occurrences of a few query
|
||||
terms than on documents that match most clauses, which is most of time
|
||||
undesirable. The new BM25Similarity does not suffer from this problem since it
|
||||
has better saturation for the contribution of the term frequency so the coord
|
||||
factors have been removed from scores. Things now work as if coords were always
|
||||
disabled when constructing boolean queries.
|
||||
|
|
|
@ -125,16 +125,14 @@ public final class BlendedTermQuery extends Query {
|
|||
}
|
||||
|
||||
/**
|
||||
* A {@link RewriteMethod} that adds all sub queries to a {@link BooleanQuery}
|
||||
* which has {@link BooleanQuery#isCoordDisabled() coords disabled}. This
|
||||
* {@link RewriteMethod} is useful when matching on several fields is
|
||||
* A {@link RewriteMethod} that adds all sub queries to a {@link BooleanQuery}.
|
||||
* This {@link RewriteMethod} is useful when matching on several fields is
|
||||
* considered better than having a good match on a single field.
|
||||
*/
|
||||
public static final RewriteMethod BOOLEAN_REWRITE = new RewriteMethod() {
|
||||
@Override
|
||||
public Query rewrite(Query[] subQueries) {
|
||||
BooleanQuery.Builder merged = new BooleanQuery.Builder();
|
||||
merged.setDisableCoord(true);
|
||||
for (Query query : subQueries) {
|
||||
merged.add(query, Occur.SHOULD);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import java.util.Set;
|
|||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.similarities.Similarity;
|
||||
|
||||
/** A Query that matches documents matching boolean combinations of other
|
||||
* queries, e.g. {@link TermQuery}s, {@link PhraseQuery}s or other
|
||||
|
@ -74,24 +73,12 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
|
|||
/** A builder for boolean queries. */
|
||||
public static class Builder {
|
||||
|
||||
private boolean disableCoord;
|
||||
private int minimumNumberShouldMatch;
|
||||
private final List<BooleanClause> clauses = new ArrayList<>();
|
||||
|
||||
/** Sole constructor. */
|
||||
public Builder() {}
|
||||
|
||||
/**
|
||||
* {@link Similarity#coord(int,int)} may be disabled in scoring, as
|
||||
* appropriate. For example, this score factor does not make sense for most
|
||||
* automatically generated queries, like {@link WildcardQuery} and {@link
|
||||
* FuzzyQuery}.
|
||||
*/
|
||||
public Builder setDisableCoord(boolean disableCoord) {
|
||||
this.disableCoord = disableCoord;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a minimum number of the optional BooleanClauses
|
||||
* which must be satisfied.
|
||||
|
@ -142,19 +129,17 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
|
|||
/** Create a new {@link BooleanQuery} based on the parameters that have
|
||||
* been set on this builder. */
|
||||
public BooleanQuery build() {
|
||||
return new BooleanQuery(disableCoord, minimumNumberShouldMatch, clauses.toArray(new BooleanClause[0]));
|
||||
return new BooleanQuery(minimumNumberShouldMatch, clauses.toArray(new BooleanClause[0]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final boolean disableCoord;
|
||||
private final int minimumNumberShouldMatch;
|
||||
private final List<BooleanClause> clauses; // used for toString() and getClauses()
|
||||
private final Map<Occur, Collection<Query>> clauseSets; // used for equals/hashcode
|
||||
|
||||
private BooleanQuery(boolean disableCoord, int minimumNumberShouldMatch,
|
||||
private BooleanQuery(int minimumNumberShouldMatch,
|
||||
BooleanClause[] clauses) {
|
||||
this.disableCoord = disableCoord;
|
||||
this.minimumNumberShouldMatch = minimumNumberShouldMatch;
|
||||
this.clauses = Collections.unmodifiableList(Arrays.asList(clauses));
|
||||
clauseSets = new EnumMap<>(Occur.class);
|
||||
|
@ -169,13 +154,6 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the coord factor is disabled.
|
||||
*/
|
||||
public boolean isCoordDisabled() {
|
||||
return disableCoord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum number of the optional BooleanClauses
|
||||
* which must be satisfied.
|
||||
|
@ -223,7 +201,7 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
|
|||
if (needsScores == false) {
|
||||
query = rewriteNoScoring();
|
||||
}
|
||||
return new BooleanWeight(query, searcher, needsScores, disableCoord);
|
||||
return new BooleanWeight(query, searcher, needsScores);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -258,7 +236,6 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
|
|||
// recursively rewrite
|
||||
{
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.setDisableCoord(isCoordDisabled());
|
||||
builder.setMinimumNumberShouldMatch(getMinimumNumberShouldMatch());
|
||||
boolean actuallyRewritten = false;
|
||||
for (BooleanClause clause : this) {
|
||||
|
@ -284,7 +261,6 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
|
|||
// since clauseSets implicitly deduplicates FILTER and MUST_NOT
|
||||
// clauses, this means there were duplicates
|
||||
BooleanQuery.Builder rewritten = new BooleanQuery.Builder();
|
||||
rewritten.setDisableCoord(disableCoord);
|
||||
rewritten.setMinimumNumberShouldMatch(minimumNumberShouldMatch);
|
||||
for (Map.Entry<Occur, Collection<Query>> entry : clauseSets.entrySet()) {
|
||||
final Occur occur = entry.getKey();
|
||||
|
@ -304,7 +280,6 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
|
|||
modified |= filters.removeAll(clauseSets.get(Occur.MUST));
|
||||
if (modified) {
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.setDisableCoord(isCoordDisabled());
|
||||
builder.setMinimumNumberShouldMatch(getMinimumNumberShouldMatch());
|
||||
for (BooleanClause clause : clauses) {
|
||||
if (clause.getOccur() != Occur.FILTER) {
|
||||
|
@ -355,7 +330,6 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
|
|||
|
||||
// now add back the SHOULD clauses
|
||||
builder = new BooleanQuery.Builder()
|
||||
.setDisableCoord(isCoordDisabled())
|
||||
.setMinimumNumberShouldMatch(getMinimumNumberShouldMatch())
|
||||
.add(rewritten, Occur.MUST);
|
||||
for (Query query : clauseSets.get(Occur.SHOULD)) {
|
||||
|
@ -414,7 +388,6 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
|
|||
* Compares the specified object with this boolean query for equality.
|
||||
* Returns true if and only if the provided object<ul>
|
||||
* <li>is also a {@link BooleanQuery},</li>
|
||||
* <li>has the same value of {@link #isCoordDisabled()}</li>
|
||||
* <li>has the same value of {@link #getMinimumNumberShouldMatch()}</li>
|
||||
* <li>has the same {@link Occur#SHOULD} clauses, regardless of the order</li>
|
||||
* <li>has the same {@link Occur#MUST} clauses, regardless of the order</li>
|
||||
|
@ -431,12 +404,11 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
|
|||
|
||||
private boolean equalsTo(BooleanQuery other) {
|
||||
return getMinimumNumberShouldMatch() == other.getMinimumNumberShouldMatch() &&
|
||||
disableCoord == other.disableCoord &&
|
||||
clauseSets.equals(other.clauseSets);
|
||||
}
|
||||
|
||||
private int computeHashCode() {
|
||||
int hashCode = Objects.hash(disableCoord, minimumNumberShouldMatch, clauseSets);
|
||||
int hashCode = Objects.hash(minimumNumberShouldMatch, clauseSets);
|
||||
if (hashCode == 0) {
|
||||
hashCode = 1;
|
||||
}
|
||||
|
|
|
@ -117,7 +117,6 @@ final class BooleanScorer extends BulkScorer {
|
|||
// This is basically an inlined FixedBitSet... seems to help with bound checks
|
||||
final long[] matching = new long[SET_SIZE];
|
||||
|
||||
final float[] coordFactors;
|
||||
final BulkScorerAndDoc[] leads;
|
||||
final HeadPriorityQueue head;
|
||||
final TailPriorityQueue tail;
|
||||
|
@ -146,7 +145,7 @@ final class BooleanScorer extends BulkScorer {
|
|||
|
||||
final OrCollector orCollector = new OrCollector();
|
||||
|
||||
BooleanScorer(BooleanWeight weight, boolean disableCoord, int maxCoord, Collection<BulkScorer> scorers, int minShouldMatch, boolean needsScores) {
|
||||
BooleanScorer(BooleanWeight weight, Collection<BulkScorer> scorers, int minShouldMatch, boolean needsScores) {
|
||||
if (minShouldMatch < 1 || minShouldMatch > scorers.size()) {
|
||||
throw new IllegalArgumentException("minShouldMatch should be within 1..num_scorers. Got " + minShouldMatch);
|
||||
}
|
||||
|
@ -172,11 +171,6 @@ final class BooleanScorer extends BulkScorer {
|
|||
}
|
||||
}
|
||||
this.cost = cost(scorers, minShouldMatch);
|
||||
|
||||
coordFactors = new float[scorers.size() + 1];
|
||||
for (int i = 0; i < coordFactors.length; i++) {
|
||||
coordFactors[i] = disableCoord ? 1.0f : weight.coord(i, maxCoord);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -189,7 +183,7 @@ final class BooleanScorer extends BulkScorer {
|
|||
final Bucket bucket = buckets[i];
|
||||
if (bucket.freq >= minShouldMatch) {
|
||||
fakeScorer.freq = bucket.freq;
|
||||
fakeScorer.score = (float) bucket.score * coordFactors[bucket.freq];
|
||||
fakeScorer.score = (float) bucket.score;
|
||||
final int doc = base | i;
|
||||
fakeScorer.doc = doc;
|
||||
collector.collect(doc);
|
||||
|
@ -275,20 +269,20 @@ final class BooleanScorer extends BulkScorer {
|
|||
}
|
||||
}
|
||||
|
||||
private void scoreWindowSingleScorer(BulkScorerAndDoc bulkScorer, LeafCollector collector, LeafCollector singleClauseCollector,
|
||||
private void scoreWindowSingleScorer(BulkScorerAndDoc bulkScorer, LeafCollector collector,
|
||||
Bits acceptDocs, int windowMin, int windowMax, int max) throws IOException {
|
||||
assert tail.size() == 0;
|
||||
final int nextWindowBase = head.top().next & ~MASK;
|
||||
final int end = Math.max(windowMax, Math.min(max, nextWindowBase));
|
||||
|
||||
bulkScorer.score(singleClauseCollector, acceptDocs, windowMin, end);
|
||||
|
||||
|
||||
bulkScorer.score(collector, acceptDocs, windowMin, end);
|
||||
|
||||
// reset the scorer that should be used for the general case
|
||||
collector.setScorer(fakeScorer);
|
||||
}
|
||||
|
||||
private BulkScorerAndDoc scoreWindow(BulkScorerAndDoc top, LeafCollector collector,
|
||||
LeafCollector singleClauseCollector, Bits acceptDocs, int min, int max) throws IOException {
|
||||
Bits acceptDocs, int min, int max) throws IOException {
|
||||
final int windowBase = top.next & ~MASK; // find the window that the next match belongs to
|
||||
final int windowMin = Math.max(min, windowBase);
|
||||
final int windowMax = Math.min(max, windowBase + SIZE);
|
||||
|
@ -304,7 +298,7 @@ final class BooleanScorer extends BulkScorer {
|
|||
// special case: only one scorer can match in the current window,
|
||||
// we can collect directly
|
||||
final BulkScorerAndDoc bulkScorer = leads[0];
|
||||
scoreWindowSingleScorer(bulkScorer, collector, singleClauseCollector, acceptDocs, windowMin, windowMax, max);
|
||||
scoreWindowSingleScorer(bulkScorer, collector, acceptDocs, windowMin, windowMax, max);
|
||||
return head.add(bulkScorer);
|
||||
} else {
|
||||
// general case, collect through a bit set first and then replay
|
||||
|
@ -318,21 +312,9 @@ final class BooleanScorer extends BulkScorer {
|
|||
fakeScorer.doc = -1;
|
||||
collector.setScorer(fakeScorer);
|
||||
|
||||
final LeafCollector singleClauseCollector;
|
||||
if (coordFactors[1] == 1f) {
|
||||
singleClauseCollector = collector;
|
||||
} else {
|
||||
singleClauseCollector = new FilterLeafCollector(collector) {
|
||||
@Override
|
||||
public void setScorer(Scorer scorer) throws IOException {
|
||||
super.setScorer(new BooleanTopLevelScorers.BoostedScorer(scorer, coordFactors[1]));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
BulkScorerAndDoc top = advance(min);
|
||||
while (top.next < max) {
|
||||
top = scoreWindow(top, collector, singleClauseCollector, acceptDocs, min, max);
|
||||
top = scoreWindow(top, collector, acceptDocs, min, max);
|
||||
}
|
||||
|
||||
return top.next;
|
||||
|
|
|
@ -1,182 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.search;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.lucene.util.Bits;
|
||||
|
||||
/** Internal document-at-a-time scorers used to deal with stupid coord() computation */
|
||||
class BooleanTopLevelScorers {
|
||||
|
||||
/**
|
||||
* Used when there is more than one scorer in a query, but a segment
|
||||
* only had one non-null scorer. This just wraps that scorer directly
|
||||
* to factor in coord().
|
||||
*/
|
||||
static class BoostedScorer extends FilterScorer {
|
||||
final float boost;
|
||||
|
||||
BoostedScorer(Scorer in, float boost) {
|
||||
super(in);
|
||||
this.boost = boost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float score() throws IOException {
|
||||
return in.score() * boost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ChildScorer> getChildren() {
|
||||
return Collections.singleton(new ChildScorer(in, "BOOSTED"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when there is more than one scorer in a query, but a segment
|
||||
* only had one non-null scorer.
|
||||
*/
|
||||
static class BoostedBulkScorer extends BulkScorer {
|
||||
|
||||
final BulkScorer in;
|
||||
final float boost;
|
||||
|
||||
BoostedBulkScorer(BulkScorer scorer, float boost) {
|
||||
this.in = scorer;
|
||||
this.boost = boost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int score(LeafCollector collector, Bits acceptDocs, int min, int max) throws IOException {
|
||||
final LeafCollector wrapped = new FilterLeafCollector(collector) {
|
||||
@Override
|
||||
public void setScorer(Scorer scorer) throws IOException {
|
||||
super.setScorer(new BoostedScorer(scorer, boost));
|
||||
}
|
||||
};
|
||||
return in.score(wrapped, acceptDocs, min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long cost() {
|
||||
return in.cost();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when there are both mandatory and optional clauses, but minShouldMatch
|
||||
* dictates that some of the optional clauses must match. The query is a conjunction,
|
||||
* but must compute coord based on how many optional subscorers matched (freq).
|
||||
*/
|
||||
static class CoordinatingConjunctionScorer extends ConjunctionScorer {
|
||||
private final float coords[];
|
||||
private final int reqCount;
|
||||
private final Scorer req;
|
||||
private final Scorer opt;
|
||||
|
||||
CoordinatingConjunctionScorer(Weight weight, float coords[], Scorer req, int reqCount, Scorer opt) {
|
||||
super(weight, Arrays.asList(req, opt), Arrays.asList(req, opt));
|
||||
this.coords = coords;
|
||||
this.req = req;
|
||||
this.reqCount = reqCount;
|
||||
this.opt = opt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float score() throws IOException {
|
||||
return (req.score() + opt.score()) * coords[reqCount + opt.freq()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when there are mandatory clauses with one optional clause: we compute
|
||||
* coord based on whether the optional clause matched or not.
|
||||
*/
|
||||
static class ReqSingleOptScorer extends ReqOptSumScorer {
|
||||
// coord factor if just the required part matches
|
||||
private final float coordReq;
|
||||
// coord factor if both required and optional part matches
|
||||
private final float coordBoth;
|
||||
|
||||
public ReqSingleOptScorer(Scorer reqScorer, Scorer optScorer, float coordReq, float coordBoth) {
|
||||
super(reqScorer, optScorer);
|
||||
this.coordReq = coordReq;
|
||||
this.coordBoth = coordBoth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float score() throws IOException {
|
||||
// TODO: sum into a double and cast to float if we ever send required clauses to BS1
|
||||
int curDoc = reqScorer.docID();
|
||||
float score = reqScorer.score();
|
||||
|
||||
int optScorerDoc = optIterator.docID();
|
||||
if (optScorerDoc < curDoc) {
|
||||
optScorerDoc = optIterator.advance(curDoc);
|
||||
}
|
||||
|
||||
if (optScorerDoc == curDoc) {
|
||||
score = (score + optScorer.score()) * coordBoth;
|
||||
} else {
|
||||
score = score * coordReq;
|
||||
}
|
||||
|
||||
return score;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when there are mandatory clauses with optional clauses: we compute
|
||||
* coord based on how many optional subscorers matched (freq).
|
||||
*/
|
||||
static class ReqMultiOptScorer extends ReqOptSumScorer {
|
||||
private final int requiredCount;
|
||||
private final float coords[];
|
||||
|
||||
public ReqMultiOptScorer(Scorer reqScorer, Scorer optScorer, int requiredCount, float coords[]) {
|
||||
super(reqScorer, optScorer);
|
||||
this.requiredCount = requiredCount;
|
||||
this.coords = coords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float score() throws IOException {
|
||||
// TODO: sum into a double and cast to float if we ever send required clauses to BS1
|
||||
int curDoc = reqScorer.docID();
|
||||
float score = reqScorer.score();
|
||||
|
||||
int optScorerDoc = optIterator.docID();
|
||||
if (optScorerDoc < curDoc) {
|
||||
optScorerDoc = optIterator.advance(curDoc);
|
||||
}
|
||||
|
||||
if (optScorerDoc == curDoc) {
|
||||
score = (score + optScorer.score()) * coords[requiredCount + optScorer.freq()];
|
||||
} else {
|
||||
score = score * coords[requiredCount];
|
||||
}
|
||||
|
||||
return score;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,44 +40,17 @@ final class BooleanWeight extends Weight {
|
|||
final BooleanQuery query;
|
||||
|
||||
final ArrayList<Weight> weights;
|
||||
final int maxCoord; // num optional + num required
|
||||
final boolean disableCoord;
|
||||
final boolean needsScores;
|
||||
final float coords[];
|
||||
|
||||
BooleanWeight(BooleanQuery query, IndexSearcher searcher, boolean needsScores, boolean disableCoord) throws IOException {
|
||||
BooleanWeight(BooleanQuery query, IndexSearcher searcher, boolean needsScores) throws IOException {
|
||||
super(query);
|
||||
this.query = query;
|
||||
this.needsScores = needsScores;
|
||||
this.similarity = searcher.getSimilarity(needsScores);
|
||||
weights = new ArrayList<>();
|
||||
int i = 0;
|
||||
int maxCoord = 0;
|
||||
for (BooleanClause c : query) {
|
||||
Weight w = searcher.createWeight(c.getQuery(), needsScores && c.isScoring());
|
||||
weights.add(w);
|
||||
if (c.isScoring()) {
|
||||
maxCoord++;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
this.maxCoord = maxCoord;
|
||||
|
||||
// precompute coords (0..N, N).
|
||||
// set disableCoord when its explicit, scores are not needed, no scoring clauses, or the sim doesn't use it.
|
||||
coords = new float[maxCoord+1];
|
||||
Arrays.fill(coords, 1F);
|
||||
coords[0] = 0f;
|
||||
if (maxCoord > 0 && needsScores && disableCoord == false) {
|
||||
// compute coords from the similarity, look for any actual ones.
|
||||
boolean seenActualCoord = false;
|
||||
for (i = 1; i < coords.length; i++) {
|
||||
coords[i] = coord(i, maxCoord);
|
||||
seenActualCoord |= (coords[i] != 1F);
|
||||
}
|
||||
this.disableCoord = seenActualCoord == false;
|
||||
} else {
|
||||
this.disableCoord = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,22 +82,6 @@ final class BooleanWeight extends Weight {
|
|||
return sum ;
|
||||
}
|
||||
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
if (overlap == 0) {
|
||||
// special case that there are only non-scoring clauses
|
||||
return 0F;
|
||||
} else if (maxOverlap == 1) {
|
||||
// LUCENE-4300: in most cases of maxOverlap=1, BQ rewrites itself away,
|
||||
// so coord() is not applied. But when BQ cannot optimize itself away
|
||||
// for a single clause (minNrShouldMatch, prohibited clauses, etc), it's
|
||||
// important not to apply coord(1,1) for consistency, it might not be 1.0F
|
||||
return 1F;
|
||||
} else {
|
||||
// common case: use the similarity to compute the coord
|
||||
return similarity.coord(overlap, maxOverlap);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void normalize(float norm, float boost) {
|
||||
for (Weight w : weights) {
|
||||
|
@ -137,7 +94,6 @@ final class BooleanWeight extends Weight {
|
|||
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
|
||||
final int minShouldMatch = query.getMinimumNumberShouldMatch();
|
||||
List<Explanation> subs = new ArrayList<>();
|
||||
int coord = 0;
|
||||
float sum = 0.0f;
|
||||
boolean fail = false;
|
||||
int matchCount = 0;
|
||||
|
@ -151,7 +107,6 @@ final class BooleanWeight extends Weight {
|
|||
if (c.isScoring()) {
|
||||
subs.add(e);
|
||||
sum += e.getValue();
|
||||
coord++;
|
||||
} else if (c.isRequired()) {
|
||||
subs.add(Explanation.match(0f, "match on required clause, product of:",
|
||||
Explanation.match(0f, Occur.FILTER + " clause"), e));
|
||||
|
@ -178,13 +133,7 @@ final class BooleanWeight extends Weight {
|
|||
return Explanation.noMatch("Failure to match minimum number of optional clauses: " + minShouldMatch, subs);
|
||||
} else {
|
||||
// we have a match
|
||||
Explanation result = Explanation.match(sum, "sum of:", subs);
|
||||
final float coordFactor = disableCoord ? 1.0f : coord(coord, maxCoord);
|
||||
if (coordFactor != 1f) {
|
||||
result = Explanation.match(sum * coordFactor, "product of:",
|
||||
result, Explanation.match(coordFactor, "coord("+coord+"/"+maxCoord+")"));
|
||||
}
|
||||
return result;
|
||||
return Explanation.match(sum, "sum of:", subs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,15 +193,10 @@ final class BooleanWeight extends Weight {
|
|||
}
|
||||
|
||||
if (optional.size() == 1) {
|
||||
BulkScorer opt = optional.get(0);
|
||||
if (!disableCoord && maxCoord > 1) {
|
||||
return new BooleanTopLevelScorers.BoostedBulkScorer(opt, coord(1, maxCoord));
|
||||
} else {
|
||||
return opt;
|
||||
}
|
||||
return optional.get(0);
|
||||
}
|
||||
|
||||
return new BooleanScorer(this, disableCoord, maxCoord, optional, Math.max(1, query.getMinimumNumberShouldMatch()), needsScores);
|
||||
return new BooleanScorer(this, optional, Math.max(1, query.getMinimumNumberShouldMatch()), needsScores);
|
||||
}
|
||||
|
||||
// Return a BulkScorer for the required clauses only,
|
||||
|
@ -275,12 +219,8 @@ final class BooleanWeight extends Weight {
|
|||
// no matches
|
||||
return null;
|
||||
}
|
||||
if (c.isScoring() == false) {
|
||||
if (needsScores) {
|
||||
scorer = disableScoring(scorer);
|
||||
}
|
||||
} else {
|
||||
assert maxCoord == 1;
|
||||
if (c.isScoring() == false && needsScores) {
|
||||
scorer = disableScoring(scorer);
|
||||
}
|
||||
}
|
||||
return scorer;
|
||||
|
@ -350,7 +290,7 @@ final class BooleanWeight extends Weight {
|
|||
if (prohibited.isEmpty()) {
|
||||
return positiveScorer;
|
||||
} else {
|
||||
Scorer prohibitedScorer = opt(prohibited, 1, true);
|
||||
Scorer prohibitedScorer = opt(prohibited, 1);
|
||||
if (prohibitedScorer.twoPhaseIterator() != null) {
|
||||
// ReqExclBulkScorer can't deal efficiently with two-phased prohibited clauses
|
||||
return null;
|
||||
|
@ -432,51 +372,33 @@ final class BooleanWeight extends Weight {
|
|||
|
||||
// pure conjunction
|
||||
if (optional.isEmpty()) {
|
||||
return excl(req(required, requiredScoring, disableCoord), prohibited);
|
||||
return excl(req(required, requiredScoring), prohibited);
|
||||
}
|
||||
|
||||
// pure disjunction
|
||||
if (required.isEmpty()) {
|
||||
return excl(opt(optional, minShouldMatch, disableCoord), prohibited);
|
||||
return excl(opt(optional, minShouldMatch), prohibited);
|
||||
}
|
||||
|
||||
// conjunction-disjunction mix:
|
||||
// we create the required and optional pieces with coord disabled, and then
|
||||
// we create the required and optional pieces, and then
|
||||
// combine the two: if minNrShouldMatch > 0, then it's a conjunction: because the
|
||||
// optional side must match. otherwise it's required + optional, factoring the
|
||||
// number of optional terms into the coord calculation
|
||||
// optional side must match. otherwise it's required + optional
|
||||
|
||||
Scorer req = excl(req(required, requiredScoring, true), prohibited);
|
||||
Scorer opt = opt(optional, minShouldMatch, true);
|
||||
Scorer req = excl(req(required, requiredScoring), prohibited);
|
||||
Scorer opt = opt(optional, minShouldMatch);
|
||||
|
||||
// TODO: clean this up: it's horrible
|
||||
if (disableCoord) {
|
||||
if (minShouldMatch > 0) {
|
||||
return new ConjunctionScorer(this, Arrays.asList(req, opt), Arrays.asList(req, opt), 1F);
|
||||
} else {
|
||||
return new ReqOptSumScorer(req, opt);
|
||||
}
|
||||
} else if (optional.size() == 1) {
|
||||
if (minShouldMatch > 0) {
|
||||
return new ConjunctionScorer(this, Arrays.asList(req, opt), Arrays.asList(req, opt), coord(requiredScoring.size()+1, maxCoord));
|
||||
} else {
|
||||
float coordReq = coord(requiredScoring.size(), maxCoord);
|
||||
float coordBoth = coord(requiredScoring.size() + 1, maxCoord);
|
||||
return new BooleanTopLevelScorers.ReqSingleOptScorer(req, opt, coordReq, coordBoth);
|
||||
}
|
||||
if (minShouldMatch > 0) {
|
||||
return new ConjunctionScorer(this, Arrays.asList(req, opt), Arrays.asList(req, opt));
|
||||
} else {
|
||||
if (minShouldMatch > 0) {
|
||||
return new BooleanTopLevelScorers.CoordinatingConjunctionScorer(this, coords, req, requiredScoring.size(), opt);
|
||||
} else {
|
||||
return new BooleanTopLevelScorers.ReqMultiOptScorer(req, opt, requiredScoring.size(), coords);
|
||||
}
|
||||
return new ReqOptSumScorer(req, opt);
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a new scorer for the given required clauses. Note that
|
||||
* {@code requiredScoring} is a subset of {@code required} containing
|
||||
* required clauses that should participate in scoring. */
|
||||
private Scorer req(List<Scorer> required, List<Scorer> requiredScoring, boolean disableCoord) {
|
||||
private Scorer req(List<Scorer> required, List<Scorer> requiredScoring) {
|
||||
if (required.size() == 1) {
|
||||
Scorer req = required.get(0);
|
||||
|
||||
|
@ -500,17 +422,9 @@ final class BooleanWeight extends Weight {
|
|||
};
|
||||
}
|
||||
|
||||
float boost = 1f;
|
||||
if (disableCoord == false) {
|
||||
boost = coord(1, maxCoord);
|
||||
}
|
||||
if (boost == 1f) {
|
||||
return req;
|
||||
}
|
||||
return new BooleanTopLevelScorers.BoostedScorer(req, boost);
|
||||
return req;
|
||||
} else {
|
||||
return new ConjunctionScorer(this, required, requiredScoring,
|
||||
disableCoord ? 1.0F : coord(requiredScoring.size(), maxCoord));
|
||||
return new ConjunctionScorer(this, required, requiredScoring);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -520,34 +434,17 @@ final class BooleanWeight extends Weight {
|
|||
} else if (prohibited.size() == 1) {
|
||||
return new ReqExclScorer(main, prohibited.get(0));
|
||||
} else {
|
||||
float coords[] = new float[prohibited.size()+1];
|
||||
Arrays.fill(coords, 1F);
|
||||
return new ReqExclScorer(main, new DisjunctionSumScorer(this, prohibited, coords, false));
|
||||
return new ReqExclScorer(main, new DisjunctionSumScorer(this, prohibited, false));
|
||||
}
|
||||
}
|
||||
|
||||
private Scorer opt(List<Scorer> optional, int minShouldMatch, boolean disableCoord) throws IOException {
|
||||
private Scorer opt(List<Scorer> optional, int minShouldMatch) throws IOException {
|
||||
if (optional.size() == 1) {
|
||||
Scorer opt = optional.get(0);
|
||||
if (!disableCoord && maxCoord > 1) {
|
||||
return new BooleanTopLevelScorers.BoostedScorer(opt, coord(1, maxCoord));
|
||||
} else {
|
||||
return opt;
|
||||
}
|
||||
return optional.get(0);
|
||||
} else if (minShouldMatch > 1) {
|
||||
return new MinShouldMatchSumScorer(this, optional, minShouldMatch);
|
||||
} else {
|
||||
float coords[];
|
||||
if (disableCoord) {
|
||||
// sneaky: when we do a mixed conjunction/disjunction, we need a fake for the disjunction part.
|
||||
coords = new float[optional.size()+1];
|
||||
Arrays.fill(coords, 1F);
|
||||
} else {
|
||||
coords = this.coords;
|
||||
}
|
||||
if (minShouldMatch > 1) {
|
||||
return new MinShouldMatchSumScorer(this, optional, minShouldMatch, coords);
|
||||
} else {
|
||||
return new DisjunctionSumScorer(this, optional, coords, needsScores);
|
||||
}
|
||||
return new DisjunctionSumScorer(this, optional, needsScores);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,17 +27,11 @@ class ConjunctionScorer extends Scorer {
|
|||
|
||||
final DocIdSetIterator disi;
|
||||
final Scorer[] scorers;
|
||||
final float coord;
|
||||
|
||||
ConjunctionScorer(Weight weight, List<Scorer> required, List<Scorer> scorers) {
|
||||
this(weight, required, scorers, 1f);
|
||||
}
|
||||
|
||||
/** Create a new {@link ConjunctionScorer}, note that {@code scorers} must be a subset of {@code required}. */
|
||||
ConjunctionScorer(Weight weight, List<Scorer> required, List<Scorer> scorers, float coord) {
|
||||
ConjunctionScorer(Weight weight, List<Scorer> required, List<Scorer> scorers) {
|
||||
super(weight);
|
||||
assert required.containsAll(scorers);
|
||||
this.coord = coord;
|
||||
this.disi = ConjunctionDISI.intersectScorers(required);
|
||||
this.scorers = scorers.toArray(new Scorer[scorers.size()]);
|
||||
}
|
||||
|
@ -63,7 +57,7 @@ class ConjunctionScorer extends Scorer {
|
|||
for (Scorer scorer : scorers) {
|
||||
sum += scorer.score();
|
||||
}
|
||||
return coord * (float)sum;
|
||||
return (float) sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,27 +22,22 @@ import java.util.List;
|
|||
|
||||
/** A Scorer for OR like queries, counterpart of <code>ConjunctionScorer</code>.
|
||||
*/
|
||||
final class DisjunctionSumScorer extends DisjunctionScorer {
|
||||
private final float[] coord;
|
||||
final class DisjunctionSumScorer extends DisjunctionScorer {
|
||||
|
||||
/** Construct a <code>DisjunctionScorer</code>.
|
||||
* @param weight The weight to be used.
|
||||
* @param subScorers Array of at least two subscorers.
|
||||
* @param coord Table of coordination factors
|
||||
*/
|
||||
DisjunctionSumScorer(Weight weight, List<Scorer> subScorers, float[] coord, boolean needsScores) {
|
||||
DisjunctionSumScorer(Weight weight, List<Scorer> subScorers, boolean needsScores) {
|
||||
super(weight, subScorers, needsScores);
|
||||
this.coord = coord;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float score(DisiWrapper topList) throws IOException {
|
||||
double score = 0;
|
||||
int freq = 0;
|
||||
for (DisiWrapper w = topList; w != null; w = w.next) {
|
||||
score += w.scorer.score();
|
||||
freq += 1;
|
||||
}
|
||||
return (float)score * coord[freq];
|
||||
return (float)score;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,7 +78,6 @@ final class MinShouldMatchSumScorer extends Scorer {
|
|||
}
|
||||
|
||||
final int minShouldMatch;
|
||||
final float[] coord;
|
||||
|
||||
// list of scorers which 'lead' the iteration and are currently
|
||||
// positioned on 'doc'
|
||||
|
@ -98,7 +97,7 @@ final class MinShouldMatchSumScorer extends Scorer {
|
|||
final Collection<ChildScorer> childScorers;
|
||||
final long cost;
|
||||
|
||||
MinShouldMatchSumScorer(Weight weight, Collection<Scorer> scorers, int minShouldMatch, float[] coord) {
|
||||
MinShouldMatchSumScorer(Weight weight, Collection<Scorer> scorers, int minShouldMatch) {
|
||||
super(weight);
|
||||
|
||||
if (minShouldMatch > scorers.size()) {
|
||||
|
@ -109,7 +108,6 @@ final class MinShouldMatchSumScorer extends Scorer {
|
|||
}
|
||||
|
||||
this.minShouldMatch = minShouldMatch;
|
||||
this.coord = coord;
|
||||
this.doc = -1;
|
||||
|
||||
head = new DisiPriorityQueue(scorers.size() - minShouldMatch + 1);
|
||||
|
@ -290,7 +288,7 @@ final class MinShouldMatchSumScorer extends Scorer {
|
|||
for (DisiWrapper s = lead; s != null; s = s.next) {
|
||||
score += s.scorer.score();
|
||||
}
|
||||
return coord[freq] * (float) score;
|
||||
return (float) score;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -321,7 +321,6 @@ public class MultiPhraseQuery extends Query {
|
|||
} else if (termArrays.length == 1) { // optimize one-term case
|
||||
Term[] terms = termArrays[0];
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.setDisableCoord(true);
|
||||
for (Term term : terms) {
|
||||
builder.add(new TermQuery(term), BooleanClause.Occur.SHOULD);
|
||||
}
|
||||
|
|
|
@ -157,9 +157,7 @@ public abstract class MultiTermQuery extends Query {
|
|||
|
||||
@Override
|
||||
protected BooleanQuery.Builder getTopLevelBuilder() {
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.setDisableCoord(true);
|
||||
return builder;
|
||||
return new BooleanQuery.Builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -255,9 +253,7 @@ public abstract class MultiTermQuery extends Query {
|
|||
|
||||
@Override
|
||||
protected BooleanQuery.Builder getTopLevelBuilder() {
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.setDisableCoord(true);
|
||||
return builder;
|
||||
return new BooleanQuery.Builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -54,9 +54,7 @@ public abstract class ScoringRewrite<B> extends TermCollectingRewrite<B> {
|
|||
public final static ScoringRewrite<BooleanQuery.Builder> SCORING_BOOLEAN_REWRITE = new ScoringRewrite<BooleanQuery.Builder>() {
|
||||
@Override
|
||||
protected BooleanQuery.Builder getTopLevelBuilder() {
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.setDisableCoord(true);
|
||||
return builder;
|
||||
return new BooleanQuery.Builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -522,8 +522,7 @@
|
|||
* {@link org.apache.lucene.search.Scorer Scorer} is going to be a <code>BooleanScorer2</code> created
|
||||
* from {@link org.apache.lucene.search.BooleanWeight BooleanWeight} (see the section on
|
||||
* <a href="#customQueriesExpert">custom queries</a> for info on changing this).
|
||||
* <p>Assuming a BooleanScorer2, we first initialize the Coordinator, which is used to apply the coord()
|
||||
* factor. We then get a internal Scorer based on the required, optional and prohibited parts of the query.
|
||||
* <p>Assuming a BooleanScorer2, we get a internal Scorer based on the required, optional and prohibited parts of the query.
|
||||
* Using this internal Scorer, the BooleanScorer2 then proceeds into a while loop based on the
|
||||
* {@link org.apache.lucene.search.DocIdSetIterator#nextDoc DocIdSetIterator.nextDoc()} method. The nextDoc() method advances
|
||||
* to the next document matching the query. This is an abstract method in the Scorer class and is thus
|
||||
|
|
|
@ -55,12 +55,6 @@ public class ClassicSimilarity extends TFIDFSimilarity {
|
|||
|
||||
/** Sole constructor: parameter-free */
|
||||
public ClassicSimilarity() {}
|
||||
|
||||
/** Implemented as <code>overlap / maxOverlap</code>. */
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return overlap / (float)maxOverlap;
|
||||
}
|
||||
|
||||
/** Implemented as <code>1/sqrt(sumOfSquaredWeights)</code>. */
|
||||
@Override
|
||||
|
|
|
@ -109,20 +109,6 @@ public abstract class Similarity {
|
|||
*/
|
||||
public Similarity() {}
|
||||
|
||||
/** Hook to integrate coordinate-level matching.
|
||||
* <p>
|
||||
* By default this is disabled (returns <code>1</code>), as with
|
||||
* most modern models this will only skew performance, but some
|
||||
* implementations such as {@link TFIDFSimilarity} override this.
|
||||
*
|
||||
* @param overlap the number of query terms matched in the document
|
||||
* @param maxOverlap the total number of terms in the query
|
||||
* @return a score factor based on term overlap with the query
|
||||
*/
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return 1f;
|
||||
}
|
||||
|
||||
/** Computes the normalization value for a query given the sum of the
|
||||
* normalized weights {@link SimWeight#getValueForNormalization()} of
|
||||
* each of the query terms. This value is passed back to the
|
||||
|
|
|
@ -156,10 +156,7 @@ import org.apache.lucene.util.BytesRef;
|
|||
* </li>
|
||||
*
|
||||
* <li>A document may match a multi term query without containing all
|
||||
* the terms of that query (this is correct for some of the queries),
|
||||
* and users can further reward documents matching more query terms
|
||||
* through a coordination factor, which is usually larger when
|
||||
* more terms are matched: <i>coord-factor(q,d)</i>.
|
||||
* the terms of that query (this is correct for some of the queries).
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
|
@ -175,7 +172,6 @@ import org.apache.lucene.util.BytesRef;
|
|||
* <tr>
|
||||
* <td valign="middle" align="right" rowspan="1">
|
||||
* score(q,d) =
|
||||
* <span style="color: #FF9933">coord-factor(q,d)</span> ·
|
||||
* <span style="color: #CCCC00">query-boost(q)</span> ·
|
||||
* </td>
|
||||
* <td valign="middle" align="center">
|
||||
|
@ -266,7 +262,6 @@ import org.apache.lucene.util.BytesRef;
|
|||
* <tr>
|
||||
* <td valign="middle" align="right" rowspan="1">
|
||||
* score(q,d) =
|
||||
* <A HREF="#formula_coord"><span style="color: #FF9933">coord(q,d)</span></A> ·
|
||||
* <A HREF="#formula_queryNorm"><span style="color: #FF33CC">queryNorm(q)</span></A> ·
|
||||
* </td>
|
||||
* <td valign="bottom" align="center" rowspan="1" style="text-align: center">
|
||||
|
@ -359,18 +354,6 @@ import org.apache.lucene.util.BytesRef;
|
|||
* <br> <br>
|
||||
* </li>
|
||||
*
|
||||
* <li>
|
||||
* <A NAME="formula_coord"></A>
|
||||
* <b><i>coord(q,d)</i></b>
|
||||
* is a score factor based on how many of the query terms are found in the specified document.
|
||||
* Typically, a document that contains more of the query's terms will receive a higher score
|
||||
* than another document with fewer query terms.
|
||||
* This is a search time factor computed in
|
||||
* {@link #coord(int, int) coord(q,d)}
|
||||
* by the Similarity in effect at search time.
|
||||
* <br> <br>
|
||||
* </li>
|
||||
*
|
||||
* <li><b>
|
||||
* <A NAME="formula_queryNorm"></A>
|
||||
* <i>queryNorm(q)</i>
|
||||
|
@ -512,21 +495,6 @@ public abstract class TFIDFSimilarity extends Similarity {
|
|||
*/
|
||||
public TFIDFSimilarity() {}
|
||||
|
||||
/** Computes a score factor based on the fraction of all query terms that a
|
||||
* document contains. This value is multiplied into scores.
|
||||
*
|
||||
* <p>The presence of a large portion of the query terms indicates a better
|
||||
* match with the query, so implementations of this method usually return
|
||||
* larger values when the ratio between these parameters is large and smaller
|
||||
* values when the ratio between them is small.
|
||||
*
|
||||
* @param overlap the number of query terms matched in the document
|
||||
* @param maxOverlap the total number of terms in the query
|
||||
* @return a score factor based on term overlap with the query
|
||||
*/
|
||||
@Override
|
||||
public abstract float coord(int overlap, int maxOverlap);
|
||||
|
||||
/** Computes the normalization value for a query given the sum of the squared
|
||||
* weights of each of the query terms. This value is multiplied into the
|
||||
* weight of each query term. While the classic query normalization factor is
|
||||
|
|
|
@ -137,7 +137,6 @@ public class QueryBuilder {
|
|||
if (query instanceof BooleanQuery) {
|
||||
BooleanQuery bq = (BooleanQuery) query;
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.setDisableCoord(bq.isCoordDisabled());
|
||||
builder.setMinimumNumberShouldMatch((int) (fraction * bq.clauses().size()));
|
||||
for (BooleanClause clause : bq) {
|
||||
builder.add(clause);
|
||||
|
|
|
@ -95,11 +95,6 @@ public class TestCustomNorms extends LuceneTestCase {
|
|||
return delegate;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return delegate.coord(overlap, maxOverlap);
|
||||
}
|
||||
}
|
||||
|
||||
public static class FloatEncodingBoostSimilarity extends Similarity {
|
||||
|
|
|
@ -115,7 +115,6 @@ public class TestMaxTermFrequency extends LuceneTestCase {
|
|||
return norm;
|
||||
}
|
||||
|
||||
@Override public float coord(int overlap, int maxOverlap) { return 0; }
|
||||
@Override public float queryNorm(float sumOfSquaredWeights) { return 0; }
|
||||
@Override public float tf(float freq) { return 0; }
|
||||
@Override public float idf(long docFreq, long docCount) { return 0; }
|
||||
|
|
|
@ -64,7 +64,6 @@ public class TestNorms extends LuceneTestCase {
|
|||
return state.getLength();
|
||||
}
|
||||
|
||||
@Override public float coord(int overlap, int maxOverlap) { return 0; }
|
||||
@Override public float queryNorm(float sumOfSquaredWeights) { return 0; }
|
||||
@Override public float tf(float freq) { return 0; }
|
||||
@Override public float idf(long docFreq, long docCount) { return 0; }
|
||||
|
@ -170,11 +169,6 @@ public class TestNorms extends LuceneTestCase {
|
|||
return delegate;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return delegate.coord(overlap, maxOverlap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -48,8 +48,6 @@ public class TestOmitTf extends LuceneTestCase {
|
|||
@Override public long encodeNormValue(float f) { return (long) f; }
|
||||
@Override
|
||||
public float queryNorm(float sumOfSquaredWeights) { return 1.0f; }
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) { return 1.0f; }
|
||||
@Override public float lengthNorm(FieldInvertState state) { return state.getBoost(); }
|
||||
@Override public float tf(float freq) { return freq; }
|
||||
@Override public float sloppyFreq(int distance) { return 2.0f; }
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.apache.lucene.index.IndexWriterConfig;
|
|||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.similarities.ClassicSimilarity;
|
||||
import org.apache.lucene.search.similarities.Similarity;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.IOContext;
|
||||
import org.apache.lucene.store.MockDirectoryWrapper;
|
||||
|
@ -240,7 +239,6 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
@Test
|
||||
public void testQueries01() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST);
|
||||
query.add(new TermQuery(new Term(field, "xx")), BooleanClause.Occur.MUST);
|
||||
int[] expDocNrs = {2,3};
|
||||
|
@ -250,7 +248,6 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
@Test
|
||||
public void testQueries02() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST);
|
||||
query.add(new TermQuery(new Term(field, "xx")), BooleanClause.Occur.SHOULD);
|
||||
int[] expDocNrs = {2,3,1,0};
|
||||
|
@ -260,7 +257,6 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
@Test
|
||||
public void testQueries03() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.SHOULD);
|
||||
query.add(new TermQuery(new Term(field, "xx")), BooleanClause.Occur.SHOULD);
|
||||
int[] expDocNrs = {2,3,1,0};
|
||||
|
@ -270,7 +266,6 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
@Test
|
||||
public void testQueries04() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.SHOULD);
|
||||
query.add(new TermQuery(new Term(field, "xx")), BooleanClause.Occur.MUST_NOT);
|
||||
int[] expDocNrs = {1,0};
|
||||
|
@ -280,7 +275,6 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
@Test
|
||||
public void testQueries05() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST);
|
||||
query.add(new TermQuery(new Term(field, "xx")), BooleanClause.Occur.MUST_NOT);
|
||||
int[] expDocNrs = {1,0};
|
||||
|
@ -290,7 +284,6 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
@Test
|
||||
public void testQueries06() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST);
|
||||
query.add(new TermQuery(new Term(field, "xx")), BooleanClause.Occur.MUST_NOT);
|
||||
query.add(new TermQuery(new Term(field, "w5")), BooleanClause.Occur.MUST_NOT);
|
||||
|
@ -301,7 +294,6 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
@Test
|
||||
public void testQueries07() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST_NOT);
|
||||
query.add(new TermQuery(new Term(field, "xx")), BooleanClause.Occur.MUST_NOT);
|
||||
query.add(new TermQuery(new Term(field, "w5")), BooleanClause.Occur.MUST_NOT);
|
||||
|
@ -312,7 +304,6 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
@Test
|
||||
public void testQueries08() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST);
|
||||
query.add(new TermQuery(new Term(field, "xx")), BooleanClause.Occur.SHOULD);
|
||||
query.add(new TermQuery(new Term(field, "w5")), BooleanClause.Occur.MUST_NOT);
|
||||
|
@ -323,7 +314,6 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
@Test
|
||||
public void testQueries09() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST);
|
||||
query.add(new TermQuery(new Term(field, "xx")), BooleanClause.Occur.MUST);
|
||||
query.add(new TermQuery(new Term(field, "w2")), BooleanClause.Occur.MUST);
|
||||
|
@ -332,33 +322,6 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
queriesTest(query.build(), expDocNrs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueries10() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(field, "w3")), BooleanClause.Occur.MUST);
|
||||
query.add(new TermQuery(new Term(field, "xx")), BooleanClause.Occur.MUST);
|
||||
query.add(new TermQuery(new Term(field, "w2")), BooleanClause.Occur.MUST);
|
||||
query.add(new TermQuery(new Term(field, "zz")), BooleanClause.Occur.SHOULD);
|
||||
|
||||
int[] expDocNrs = {2, 3};
|
||||
Similarity oldSimilarity = searcher.getSimilarity(true);
|
||||
Similarity newSimilarity = new ClassicSimilarity() {
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return overlap / ((float)maxOverlap - 1);
|
||||
}
|
||||
};
|
||||
try {
|
||||
searcher.setSimilarity(newSimilarity);
|
||||
singleSegmentSearcher.setSimilarity(newSimilarity);
|
||||
queriesTest(query.build(), expDocNrs);
|
||||
} finally {
|
||||
searcher.setSimilarity(oldSimilarity);
|
||||
singleSegmentSearcher.setSimilarity(oldSimilarity);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomQueries() throws Exception {
|
||||
String[] vals = {"w1","w2","w3","w4","w5","xx","yy","zzz"};
|
||||
|
@ -434,7 +397,6 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
// more than once.
|
||||
public static BooleanQuery.Builder randBoolQuery(Random rnd, boolean allowMust, int level, String field, String[] vals, Callback cb) {
|
||||
BooleanQuery.Builder current = new BooleanQuery.Builder();
|
||||
current.setDisableCoord(rnd.nextBoolean());
|
||||
for (int i=0; i<rnd.nextInt(vals.length)+1; i++) {
|
||||
int qType=0; // term query
|
||||
if (level>0) {
|
||||
|
|
|
@ -1,860 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.search;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.StringField;
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.FieldInvertState;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.similarities.Similarity;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
/**
|
||||
* Tests coord() computation by BooleanQuery
|
||||
*/
|
||||
public class TestBooleanCoord extends LuceneTestCase {
|
||||
static Directory dir;
|
||||
static DirectoryReader reader;
|
||||
static IndexSearcher searcher;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
dir = newDirectory();
|
||||
IndexWriter iw = new IndexWriter(dir, new IndexWriterConfig(null));
|
||||
|
||||
// we only add two documents for testing:
|
||||
// the first document has 3 terms A,B,C (for positive matching). we test scores against this.
|
||||
// the second document has 3 negative terms 1,2,3 that exist in the segment (for non-null scorers)
|
||||
// to test terms that don't exist (null scorers), we use X,Y,Z
|
||||
|
||||
Document doc = new Document();
|
||||
doc.add(new StringField("field", "A", Field.Store.NO));
|
||||
doc.add(new StringField("field", "B", Field.Store.NO));
|
||||
doc.add(new StringField("field", "C", Field.Store.NO));
|
||||
iw.addDocument(doc);
|
||||
|
||||
doc = new Document();
|
||||
doc.add(new StringField("field", "1", Field.Store.NO));
|
||||
doc.add(new StringField("field", "2", Field.Store.NO));
|
||||
doc.add(new StringField("field", "3", Field.Store.NO));
|
||||
iw.addDocument(doc);
|
||||
|
||||
iw.close();
|
||||
reader = DirectoryReader.open(dir);
|
||||
searcher = new IndexSearcher(reader);
|
||||
// we set a similarity that just returns 1, the idea is to test coord
|
||||
searcher.setSimilarity(new Similarity() {
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
// we use a rather bogus/complex coord, because today coord() can really return anything.
|
||||
// note in the case of overlap == maxOverlap == 1: BooleanWeight always applies 1, (see LUCENE-4300).
|
||||
return overlap / (float)(maxOverlap + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long computeNorm(FieldInvertState state) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimWeight computeWeight(CollectionStatistics collectionStats, TermStatistics... termStats) {
|
||||
return new SimWeight() {
|
||||
@Override
|
||||
public float getValueForNormalization() {
|
||||
return 1f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void normalize(float queryNorm, float topLevelBoost) {}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimScorer simScorer(SimWeight weight, LeafReaderContext context) throws IOException {
|
||||
return new SimScorer() {
|
||||
@Override
|
||||
public float score(int doc, float freq) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float computeSlopFactor(int distance) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float computePayloadFactor(int doc, int start, int end, BytesRef payload) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
reader.close();
|
||||
reader = null;
|
||||
dir.close();
|
||||
dir = null;
|
||||
searcher = null;
|
||||
}
|
||||
|
||||
// disjunctions
|
||||
|
||||
public void testDisjunction1TermMatches() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
// LUCENE-4300: coord(1,1) is always treated as 1
|
||||
assertScore(1 * 1, bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction2TermMatches() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(2f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction1OutOf2() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(2f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction1OutOf2Missing() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(2f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction1OutOf3() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("2"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction1OutOf3MissingOne() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction1OutOf3MissingTwo() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Y"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction2OutOf3() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction2OutOf3Missing() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
// disjunctions with coord disabled
|
||||
|
||||
public void testDisjunction1TermMatchesCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction2TermMatchesCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction1OutOf2CoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction1OutOf2MissingCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction1OutOf3CoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("2"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction1OutOf3MissingOneCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction1OutOf3MissingTwoCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Y"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction2OutOf3CoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
public void testDisjunction2OutOf3MissingCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
// minShouldMatch
|
||||
public void testMinShouldMatch1TermMatches() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
// LUCENE-4300: coord(1,1) is always treated as 1
|
||||
assertScore(1 * 1, bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatchn2TermMatches() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(2f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch1OutOf2() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(2f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch1OutOf2Missing() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(2f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch1OutOf3() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("2"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch1OutOf3MissingOne() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch1OutOf3MissingTwo() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Y"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch2OutOf3() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch2OutOf3Missing() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch2OutOf4() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("2"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(4f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch2OutOf4Missing() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(4f + 1), bq.build());
|
||||
}
|
||||
|
||||
// minShouldMatch with coord disabled
|
||||
|
||||
public void testMinShouldMatch1TermMatchesCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch2TermMatchesCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch1OutOf2CoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch1OutOf2MissingCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch1OutOf3CoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("2"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch1OutOf3MissingOneCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch1OutOf3MissingTwoCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Y"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch2OutOf3CoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch2OutOf3MissingCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch2OutOf4CoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("2"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
public void testMinShouldMatch2OutOf4MissingCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
// conjunctions
|
||||
|
||||
public void testConjunction1TermMatches() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
// LUCENE-4300: coord(1,1) is always treated as 1
|
||||
assertScore(1 * 1, bq.build());
|
||||
}
|
||||
|
||||
public void testConjunction1TermMatches1Prohib() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("1"), BooleanClause.Occur.MUST_NOT);
|
||||
// LUCENE-4300: coord(1,1) is always treated as 1
|
||||
assertScore(1 * 1, bq.build());
|
||||
}
|
||||
|
||||
public void testConjunction1TermMatches2Prohib() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("1"), BooleanClause.Occur.MUST_NOT);
|
||||
bq.add(term("2"), BooleanClause.Occur.MUST_NOT);
|
||||
// LUCENE-4300: coord(1,1) is always treated as 1
|
||||
assertScore(1 * 1, bq.build());
|
||||
}
|
||||
|
||||
public void testConjunction2TermMatches() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.MUST);
|
||||
assertScore(2 * 2/(2f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testConjunction3TermMatches() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("C"), BooleanClause.Occur.MUST);
|
||||
assertScore(3 * 3/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
// conjunctions coord disabled
|
||||
|
||||
public void testConjunction1TermMatchesCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testConjunction1TermMatches1ProhibCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("1"), BooleanClause.Occur.MUST_NOT);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testConjunction1TermMatches2ProhibCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("1"), BooleanClause.Occur.MUST_NOT);
|
||||
bq.add(term("2"), BooleanClause.Occur.MUST_NOT);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testConjunction2TermMatchesCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.MUST);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
// optional + mandatory mix
|
||||
public void testMix2TermMatches() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(2f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch1OutOfTwo() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(2f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch1OutOfTwoMissing() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(2f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch1OutOfThree() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("2"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch1OutOfThreeOneMissing() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch2OutOfThree() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch2OutOfThreeMissing() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMix2TermMatchesCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch1OutOfTwoCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch1OutOfTwoMissingCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch1OutOfThreeCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("2"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1, bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch1OutOfThreeOneMissingCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(1 * 1/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch2OutOfThreeCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
public void testMixMatch2OutOfThreeMissingCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
// min should match + mandatory mix
|
||||
|
||||
public void testMixMinShouldMatch2OutOfThree() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMixMinShouldMatch2OutOfThreeMissing() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2 * 2/(3f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMixMinShouldMatch3OutOfFour() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("C"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(3 * 3/(4f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMixMinShouldMatch3OutOfFourMissing() throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("C"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(3 * 3/(4f + 1), bq.build());
|
||||
}
|
||||
|
||||
public void testMixMinShouldMatch2OutOfThreeCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
public void testMixMinShouldMatch2OutOfThreeMissingCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(1);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(2, bq.build());
|
||||
}
|
||||
|
||||
public void testMixMinShouldMatch3OutOfFourCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("C"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("1"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(3, bq.build());
|
||||
}
|
||||
|
||||
public void testMixMinShouldMatch3OutOfFourMissingCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder bq =new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.setMinimumNumberShouldMatch(2);
|
||||
bq.add(term("A"), BooleanClause.Occur.MUST);
|
||||
bq.add(term("B"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("C"), BooleanClause.Occur.SHOULD);
|
||||
bq.add(term("Z"), BooleanClause.Occur.SHOULD);
|
||||
assertScore(3, bq.build());
|
||||
}
|
||||
|
||||
// nested cases, make sure conjunctions propagate scoring
|
||||
|
||||
public void testConjunctionNested() throws Exception {
|
||||
BooleanQuery.Builder inner = new BooleanQuery.Builder();
|
||||
inner.add(term("A"), BooleanClause.Occur.MUST);
|
||||
inner.add(term("B"), BooleanClause.Occur.MUST);
|
||||
BooleanQuery.Builder outer = new BooleanQuery.Builder();
|
||||
outer.add(inner.build(), BooleanClause.Occur.MUST);
|
||||
outer.add(term("C"), BooleanClause.Occur.MUST);
|
||||
float innerScore = (1 + 1) * 2/(2f+1);
|
||||
float outerScore = (innerScore + 1) * 2/(2f+1);
|
||||
assertScore(outerScore, outer.build());
|
||||
}
|
||||
|
||||
public void testConjunctionNestedOuterCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder inner = new BooleanQuery.Builder();
|
||||
inner.add(term("A"), BooleanClause.Occur.MUST);
|
||||
inner.add(term("B"), BooleanClause.Occur.MUST);
|
||||
BooleanQuery.Builder outer = new BooleanQuery.Builder();
|
||||
outer.setDisableCoord(true);
|
||||
outer.add(inner.build(), BooleanClause.Occur.MUST);
|
||||
outer.add(term("C"), BooleanClause.Occur.MUST);
|
||||
float innerScore = (1 + 1) * 2/(2f+1);
|
||||
float outerScore = (innerScore + 1);
|
||||
assertScore(outerScore, outer.build());
|
||||
}
|
||||
|
||||
public void testConjunctionNestedInnerCoordDisabled() throws Exception {
|
||||
BooleanQuery.Builder inner = new BooleanQuery.Builder();
|
||||
inner.setDisableCoord(true);
|
||||
inner.add(term("A"), BooleanClause.Occur.MUST);
|
||||
inner.add(term("B"), BooleanClause.Occur.MUST);
|
||||
BooleanQuery.Builder outer = new BooleanQuery.Builder();
|
||||
outer.add(inner.build(), BooleanClause.Occur.MUST);
|
||||
outer.add(term("C"), BooleanClause.Occur.MUST);
|
||||
float innerScore = (1 + 1);
|
||||
float outerScore = (innerScore + 1) * 2/(2f+1);
|
||||
assertScore(outerScore, outer.build());
|
||||
}
|
||||
|
||||
public void testConjunctionNestedCoordDisabledEverywhere() throws Exception {
|
||||
BooleanQuery.Builder inner = new BooleanQuery.Builder();
|
||||
inner.setDisableCoord(true);
|
||||
inner.add(term("A"), BooleanClause.Occur.MUST);
|
||||
inner.add(term("B"), BooleanClause.Occur.MUST);
|
||||
BooleanQuery.Builder outer = new BooleanQuery.Builder();
|
||||
outer.setDisableCoord(true);
|
||||
outer.add(inner.build(), BooleanClause.Occur.MUST);
|
||||
outer.add(term("C"), BooleanClause.Occur.MUST);
|
||||
float innerScore = (1 + 1);
|
||||
float outerScore = (innerScore + 1);
|
||||
assertScore(outerScore, outer.build());
|
||||
}
|
||||
|
||||
public void testConjunctionNestedSingle() throws Exception {
|
||||
BooleanQuery.Builder inner = new BooleanQuery.Builder();
|
||||
inner.add(term("A"), BooleanClause.Occur.MUST);
|
||||
inner.add(term("B"), BooleanClause.Occur.MUST);
|
||||
BooleanQuery.Builder outer = new BooleanQuery.Builder();
|
||||
outer.add(inner.build(), BooleanClause.Occur.MUST);
|
||||
float innerScore = (1 + 1) * 2/(2f+1);
|
||||
// LUCENE-4300: coord(1,1) is always treated as 1
|
||||
float outerScore = innerScore * 1;
|
||||
assertScore(outerScore, outer.build());
|
||||
}
|
||||
|
||||
/** asserts score for our single matching good doc */
|
||||
private void assertScore(final float expected, Query query) throws Exception {
|
||||
// test in-order
|
||||
Weight weight = searcher.createNormalizedWeight(query, true);
|
||||
Scorer scorer = weight.scorer(reader.leaves().get(0));
|
||||
assertTrue(scorer.docID() == -1 || scorer.docID() == DocIdSetIterator.NO_MORE_DOCS);
|
||||
assertEquals(0, scorer.iterator().nextDoc());
|
||||
assertEquals(expected, scorer.score(), 0.0001f);
|
||||
|
||||
// test bulk scorer
|
||||
final AtomicBoolean seen = new AtomicBoolean(false);
|
||||
BulkScorer bulkScorer = weight.bulkScorer(reader.leaves().get(0));
|
||||
assertNotNull(bulkScorer);
|
||||
bulkScorer.score(new LeafCollector() {
|
||||
Scorer scorer;
|
||||
|
||||
@Override
|
||||
public void setScorer(Scorer scorer) throws IOException {
|
||||
this.scorer = scorer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(int doc) throws IOException {
|
||||
assertFalse(seen.get());
|
||||
assertEquals(0, doc);
|
||||
assertEquals(expected, scorer.score(), 0.0001f);
|
||||
seen.set(true);
|
||||
}
|
||||
}, null, 0, 1);
|
||||
assertTrue(seen.get());
|
||||
|
||||
// test the explanation
|
||||
Explanation expl = weight.explain(reader.leaves().get(0), 0);
|
||||
assertEquals(expected, expl.getValue(), 0.0001f);
|
||||
}
|
||||
|
||||
private Query term(String s) {
|
||||
return new TermQuery(new Term("field", s));
|
||||
}
|
||||
}
|
|
@ -27,8 +27,6 @@ import org.apache.lucene.document.Field;
|
|||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.similarities.ClassicSimilarity;
|
||||
import org.apache.lucene.search.similarities.Similarity;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.junit.AfterClass;
|
||||
|
@ -394,48 +392,26 @@ public class TestBooleanMinShouldMatch extends LuceneTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testRewriteCoord1() throws Exception {
|
||||
final Similarity oldSimilarity = s.getSimilarity(true);
|
||||
try {
|
||||
s.setSimilarity(new ClassicSimilarity() {
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return overlap / ((float)maxOverlap + 1);
|
||||
}
|
||||
});
|
||||
BooleanQuery.Builder q1 = new BooleanQuery.Builder();
|
||||
q1.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);
|
||||
BooleanQuery.Builder q2 = new BooleanQuery.Builder();
|
||||
q2.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);
|
||||
q2.setMinimumNumberShouldMatch(1);
|
||||
TopDocs top1 = s.search(q1.build(),100);
|
||||
TopDocs top2 = s.search(q2.build(),100);
|
||||
assertSubsetOfSameScores(q2.build(), top1, top2);
|
||||
} finally {
|
||||
s.setSimilarity(oldSimilarity);
|
||||
}
|
||||
public void testRewriteMSM1() throws Exception {
|
||||
BooleanQuery.Builder q1 = new BooleanQuery.Builder();
|
||||
q1.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);
|
||||
BooleanQuery.Builder q2 = new BooleanQuery.Builder();
|
||||
q2.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);
|
||||
q2.setMinimumNumberShouldMatch(1);
|
||||
TopDocs top1 = s.search(q1.build(),100);
|
||||
TopDocs top2 = s.search(q2.build(),100);
|
||||
assertSubsetOfSameScores(q2.build(), top1, top2);
|
||||
}
|
||||
|
||||
public void testRewriteNegate() throws Exception {
|
||||
final Similarity oldSimilarity = s.getSimilarity(true);
|
||||
try {
|
||||
s.setSimilarity(new ClassicSimilarity() {
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return overlap / ((float)maxOverlap + 1);
|
||||
}
|
||||
});
|
||||
BooleanQuery.Builder q1 = new BooleanQuery.Builder();
|
||||
q1.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);
|
||||
BooleanQuery.Builder q2 = new BooleanQuery.Builder();
|
||||
q2.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);
|
||||
q2.add(new TermQuery(new Term("data", "Z")), BooleanClause.Occur.MUST_NOT);
|
||||
TopDocs top1 = s.search(q1.build(),100);
|
||||
TopDocs top2 = s.search(q2.build(),100);
|
||||
assertSubsetOfSameScores(q2.build(), top1, top2);
|
||||
} finally {
|
||||
s.setSimilarity(oldSimilarity);
|
||||
}
|
||||
BooleanQuery.Builder q1 = new BooleanQuery.Builder();
|
||||
q1.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);
|
||||
BooleanQuery.Builder q2 = new BooleanQuery.Builder();
|
||||
q2.add(new TermQuery(new Term("data", "1")), BooleanClause.Occur.SHOULD);
|
||||
q2.add(new TermQuery(new Term("data", "Z")), BooleanClause.Occur.MUST_NOT);
|
||||
TopDocs top1 = s.search(q1.build(),100);
|
||||
TopDocs top2 = s.search(q2.build(),100);
|
||||
assertSubsetOfSameScores(q2.build(), top1, top2);
|
||||
}
|
||||
|
||||
protected void printHits(String test, ScoreDoc[] h, IndexSearcher searcher) throws Exception {
|
||||
|
|
|
@ -257,7 +257,7 @@ public class TestBooleanOr extends LuceneTestCase {
|
|||
scorer(5000, 100000, 9999998, 9999999)
|
||||
);
|
||||
Collections.shuffle(optionalScorers, random());
|
||||
BooleanScorer scorer = new BooleanScorer(null, true, 0, optionalScorers, 1, random().nextBoolean());
|
||||
BooleanScorer scorer = new BooleanScorer(null, optionalScorers, 1, random().nextBoolean());
|
||||
final List<Integer> matches = new ArrayList<>();
|
||||
scorer.score(new LeafCollector() {
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ import org.apache.lucene.index.MultiReader;
|
|||
import org.apache.lucene.index.RandomIndexWriter;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.BooleanTopLevelScorers.BoostedScorer;
|
||||
import org.apache.lucene.search.similarities.ClassicSimilarity;
|
||||
import org.apache.lucene.search.spans.SpanQuery;
|
||||
import org.apache.lucene.search.spans.SpanTermQuery;
|
||||
|
@ -94,10 +93,8 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
clauses.add(new BooleanClause(query, occur));
|
||||
}
|
||||
|
||||
final boolean disableCoord = random().nextBoolean();
|
||||
final int minShouldMatch = random().nextInt(5);
|
||||
BooleanQuery.Builder bq1Builder = new BooleanQuery.Builder();
|
||||
bq1Builder.setDisableCoord(disableCoord);
|
||||
bq1Builder.setMinimumNumberShouldMatch(minShouldMatch);
|
||||
for (BooleanClause clause : clauses) {
|
||||
bq1Builder.add(clause);
|
||||
|
@ -106,7 +103,6 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
|
||||
Collections.shuffle(clauses, random());
|
||||
BooleanQuery.Builder bq2Builder = new BooleanQuery.Builder();
|
||||
bq2Builder.setDisableCoord(disableCoord);
|
||||
bq2Builder.setMinimumNumberShouldMatch(minShouldMatch);
|
||||
for (BooleanClause clause : clauses) {
|
||||
bq2Builder.add(clause);
|
||||
|
@ -119,12 +115,10 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
|
||||
public void testEqualityOnDuplicateShouldClauses() {
|
||||
BooleanQuery bq1 = new BooleanQuery.Builder()
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.setMinimumNumberShouldMatch(random().nextInt(2))
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.SHOULD)
|
||||
.build();
|
||||
BooleanQuery bq2 = new BooleanQuery.Builder()
|
||||
.setDisableCoord(bq1.isCoordDisabled())
|
||||
.setMinimumNumberShouldMatch(bq1.getMinimumNumberShouldMatch())
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.SHOULD)
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.SHOULD)
|
||||
|
@ -134,12 +128,10 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
|
||||
public void testEqualityOnDuplicateMustClauses() {
|
||||
BooleanQuery bq1 = new BooleanQuery.Builder()
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.setMinimumNumberShouldMatch(random().nextInt(2))
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.MUST)
|
||||
.build();
|
||||
BooleanQuery bq2 = new BooleanQuery.Builder()
|
||||
.setDisableCoord(bq1.isCoordDisabled())
|
||||
.setMinimumNumberShouldMatch(bq1.getMinimumNumberShouldMatch())
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.MUST)
|
||||
|
@ -149,12 +141,10 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
|
||||
public void testEqualityOnDuplicateFilterClauses() {
|
||||
BooleanQuery bq1 = new BooleanQuery.Builder()
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.setMinimumNumberShouldMatch(random().nextInt(2))
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
.build();
|
||||
BooleanQuery bq2 = new BooleanQuery.Builder()
|
||||
.setDisableCoord(bq1.isCoordDisabled())
|
||||
.setMinimumNumberShouldMatch(bq1.getMinimumNumberShouldMatch())
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
|
@ -164,13 +154,11 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
|
||||
public void testEqualityOnDuplicateMustNotClauses() {
|
||||
BooleanQuery bq1 = new BooleanQuery.Builder()
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.setMinimumNumberShouldMatch(random().nextInt(2))
|
||||
.add(new MatchAllDocsQuery(), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
.build();
|
||||
BooleanQuery bq2 = new BooleanQuery.Builder()
|
||||
.setDisableCoord(bq1.isCoordDisabled())
|
||||
.setMinimumNumberShouldMatch(bq1.getMinimumNumberShouldMatch())
|
||||
.add(new MatchAllDocsQuery(), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
|
@ -211,29 +199,6 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
BooleanQuery.Builder q = new BooleanQuery.Builder();
|
||||
q.add(new TermQuery(new Term("field", "a")), BooleanClause.Occur.SHOULD);
|
||||
|
||||
// LUCENE-2617: make sure that a term not in the index still contributes to the score via coord factor
|
||||
float score = s.search(q.build(), 10).getMaxScore();
|
||||
Query subQuery = new BoostQuery(new TermQuery(new Term("field", "not_in_index")), 0f);
|
||||
q.add(subQuery, BooleanClause.Occur.SHOULD);
|
||||
float score2 = s.search(q.build(), 10).getMaxScore();
|
||||
assertEquals(score*.5F, score2, 1e-6);
|
||||
|
||||
// LUCENE-2617: make sure that a clause not in the index still contributes to the score via coord factor
|
||||
BooleanQuery.Builder qq = new BooleanQuery.Builder();
|
||||
for (BooleanClause clause : q.build()) {
|
||||
qq.add(clause);
|
||||
}
|
||||
PhraseQuery phrase = new PhraseQuery("field", "not_in_index", "another_not_in_index");
|
||||
qq.add(new BoostQuery(phrase, 0f), BooleanClause.Occur.SHOULD);
|
||||
score2 = s.search(qq.build(), 10).getMaxScore();
|
||||
assertEquals(score*(1/3F), score2, 1e-6);
|
||||
|
||||
// now test BooleanScorer2
|
||||
subQuery = new BoostQuery(new TermQuery(new Term("field", "b")), 0f);
|
||||
q.add(subQuery, BooleanClause.Occur.MUST);
|
||||
score2 = s.search(q.build(), 10).getMaxScore();
|
||||
assertEquals(score*(2/3F), score2, 1e-6);
|
||||
|
||||
// PhraseQuery w/ no terms added returns a null scorer
|
||||
PhraseQuery pq = new PhraseQuery("field", new String[0]);
|
||||
q.add(pq, BooleanClause.Occur.SHOULD);
|
||||
|
@ -714,7 +679,7 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
|
||||
final Weight weight = searcher.createNormalizedWeight(q.build(), random().nextBoolean());
|
||||
final Scorer scorer = weight.scorer(searcher.getIndexReader().leaves().get(0));
|
||||
assertTrue(scorer instanceof BoostedScorer || scorer instanceof ExactPhraseScorer);
|
||||
assertTrue(scorer instanceof ExactPhraseScorer);
|
||||
assertNotNull(scorer.twoPhaseIterator());
|
||||
|
||||
reader.close();
|
||||
|
|
|
@ -202,7 +202,7 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
|
|||
assertFalse(collector.getSummaries().isEmpty());
|
||||
for (String summary : collector.getSummaries()) {
|
||||
assertEquals(
|
||||
"CoordinatingConjunctionScorer\n" +
|
||||
"ConjunctionScorer\n" +
|
||||
" MUST ConstantScoreScorer\n" +
|
||||
" MUST MinShouldMatchSumScorer\n" +
|
||||
" SHOULD TermScorer body:nutch\n" +
|
||||
|
@ -222,8 +222,7 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
|
|||
assertFalse(collector.getSummaries().isEmpty());
|
||||
for (String summary : collector.getSummaries()) {
|
||||
assertEquals(
|
||||
"BoostedScorer\n" +
|
||||
" BOOSTED TermScorer body:nutch", summary);
|
||||
"TermScorer body:nutch", summary);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,28 +106,24 @@ public class TestBooleanRewrites extends LuceneTestCase {
|
|||
BooleanQuery bq = new BooleanQuery.Builder()
|
||||
.add(new MatchAllDocsQuery(), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.build();
|
||||
assertEquals(new ConstantScoreQuery(new TermQuery(new Term("foo", "bar"))), searcher.rewrite(bq));
|
||||
|
||||
bq = new BooleanQuery.Builder()
|
||||
.add(new BoostQuery(new MatchAllDocsQuery(), 42), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.build();
|
||||
assertEquals(new BoostQuery(new ConstantScoreQuery(new TermQuery(new Term("foo", "bar"))), 42), searcher.rewrite(bq));
|
||||
|
||||
bq = new BooleanQuery.Builder()
|
||||
.add(new MatchAllDocsQuery(), Occur.MUST)
|
||||
.add(new MatchAllDocsQuery(), Occur.FILTER)
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.build();
|
||||
assertEquals(new MatchAllDocsQuery(), searcher.rewrite(bq));
|
||||
|
||||
bq = new BooleanQuery.Builder()
|
||||
.add(new BoostQuery(new MatchAllDocsQuery(), 42), Occur.MUST)
|
||||
.add(new MatchAllDocsQuery(), Occur.FILTER)
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.build();
|
||||
assertEquals(new BoostQuery(new MatchAllDocsQuery(), 42), searcher.rewrite(bq));
|
||||
|
||||
|
@ -147,7 +143,6 @@ public class TestBooleanRewrites extends LuceneTestCase {
|
|||
.add(new MatchAllDocsQuery(), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
.add(new TermQuery(new Term("foo", "baz")), Occur.FILTER)
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.build();
|
||||
Query expected = new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
|
@ -159,7 +154,6 @@ public class TestBooleanRewrites extends LuceneTestCase {
|
|||
.add(new MatchAllDocsQuery(), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
.add(new TermQuery(new Term("foo", "baz")), Occur.MUST_NOT)
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.build();
|
||||
expected = new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
|
@ -182,13 +176,11 @@ public class TestBooleanRewrites extends LuceneTestCase {
|
|||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
.add(new TermQuery(new Term("foo", "baz")), Occur.SHOULD)
|
||||
.add(new TermQuery(new Term("foo", "quux")), Occur.SHOULD)
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.build();
|
||||
BooleanQuery expected = new BooleanQuery.Builder()
|
||||
.add(new ConstantScoreQuery(new TermQuery(new Term("foo", "bar"))), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "baz")), Occur.SHOULD)
|
||||
.add(new TermQuery(new Term("foo", "quux")), Occur.SHOULD)
|
||||
.setDisableCoord(bq.isCoordDisabled())
|
||||
.build();
|
||||
assertEquals(expected, searcher.rewrite(bq));
|
||||
}
|
||||
|
@ -197,7 +189,6 @@ public class TestBooleanRewrites extends LuceneTestCase {
|
|||
IndexSearcher searcher = newSearcher(new MultiReader());
|
||||
|
||||
BooleanQuery bq = new BooleanQuery.Builder()
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
.build();
|
||||
|
@ -209,7 +200,6 @@ public class TestBooleanRewrites extends LuceneTestCase {
|
|||
.add(new TermQuery(new Term("foo", "baz")), Occur.FILTER)
|
||||
.build();
|
||||
BooleanQuery expected = new BooleanQuery.Builder()
|
||||
.setDisableCoord(bq.isCoordDisabled())
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "baz")), Occur.FILTER)
|
||||
.build();
|
||||
|
@ -220,21 +210,18 @@ public class TestBooleanRewrites extends LuceneTestCase {
|
|||
IndexSearcher searcher = newSearcher(new MultiReader());
|
||||
|
||||
BooleanQuery bq = new BooleanQuery.Builder()
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.MUST)
|
||||
.add(new MatchAllDocsQuery(), Occur.FILTER)
|
||||
.build();
|
||||
assertEquals(new TermQuery(new Term("foo", "bar")), searcher.rewrite(bq));
|
||||
|
||||
bq = new BooleanQuery.Builder()
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.setMinimumNumberShouldMatch(random().nextInt(5))
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "baz")), Occur.MUST)
|
||||
.add(new MatchAllDocsQuery(), Occur.FILTER)
|
||||
.build();
|
||||
BooleanQuery expected = new BooleanQuery.Builder()
|
||||
.setDisableCoord(bq.isCoordDisabled())
|
||||
.setMinimumNumberShouldMatch(bq.getMinimumNumberShouldMatch())
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "baz")), Occur.MUST)
|
||||
|
@ -299,7 +286,6 @@ public class TestBooleanRewrites extends LuceneTestCase {
|
|||
}
|
||||
final int numClauses = random().nextInt(5);
|
||||
BooleanQuery.Builder b = new BooleanQuery.Builder();
|
||||
b.setDisableCoord(random().nextBoolean());
|
||||
int numShoulds = 0;
|
||||
for (int i = 0; i < numClauses; ++i) {
|
||||
final Occur occur = Occur.values()[random().nextInt(Occur.values().length)];
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.apache.lucene.index.RandomIndexWriter;
|
|||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.Weight.DefaultBulkScorer;
|
||||
import org.apache.lucene.search.similarities.ClassicSimilarity;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
|
@ -181,26 +180,15 @@ public class TestBooleanScorer extends LuceneTestCase {
|
|||
BulkScorer scorer = ((BooleanWeight) weight).booleanScorer(ctx);
|
||||
assertTrue(scorer instanceof DefaultBulkScorer); // term scorer
|
||||
|
||||
// disabled coords -> term scorer
|
||||
// scores -> term scorer too
|
||||
query = new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.SHOULD) // existing term
|
||||
.add(new TermQuery(new Term("foo", "baz")), Occur.SHOULD) // missing term
|
||||
.setDisableCoord(true)
|
||||
.build();
|
||||
weight = searcher.createNormalizedWeight(query, true);
|
||||
scorer = ((BooleanWeight) weight).booleanScorer(ctx);
|
||||
assertTrue(scorer instanceof DefaultBulkScorer); // term scorer
|
||||
|
||||
// enabled coords -> BoostedBulkScorer
|
||||
searcher.setSimilarity(new ClassicSimilarity());
|
||||
query = new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.SHOULD) // existing term
|
||||
.add(new TermQuery(new Term("foo", "baz")), Occur.SHOULD) // missing term
|
||||
.build();
|
||||
weight = searcher.createNormalizedWeight(query, true);
|
||||
scorer = ((BooleanWeight) weight).booleanScorer(ctx);
|
||||
assertTrue(scorer instanceof BooleanTopLevelScorers.BoostedBulkScorer);
|
||||
|
||||
w.close();
|
||||
reader.close();
|
||||
dir.close();
|
||||
|
@ -291,7 +279,6 @@ public class TestBooleanScorer extends LuceneTestCase {
|
|||
.add(new BoostQuery(new TermQuery(new Term("field", "foo")), 3), Occur.SHOULD)
|
||||
.add(new BoostQuery(new TermQuery(new Term("field", "bar")), 3), Occur.SHOULD)
|
||||
.add(new BoostQuery(new TermQuery(new Term("field", "baz")), 3), Occur.SHOULD)
|
||||
.setDisableCoord(random().nextBoolean())
|
||||
.build();
|
||||
|
||||
// duel BS1 vs. BS2
|
||||
|
|
|
@ -79,11 +79,6 @@ public class TestDocValuesScoring extends LuceneTestCase {
|
|||
return "foo".equals(field) ? fooSim : base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return base.coord(overlap, maxOverlap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float queryNorm(float sumOfSquaredWeights) {
|
||||
return base.queryNorm(sumOfSquaredWeights);
|
||||
|
|
|
@ -351,7 +351,7 @@ public class TestMinShouldMatch2 extends LuceneTestCase {
|
|||
@Override
|
||||
public float score() throws IOException {
|
||||
assert score != 0 : currentMatched;
|
||||
return (float)score * ((BooleanWeight) weight).coord(currentMatched, ((BooleanWeight) weight).maxCoord);
|
||||
return (float)score;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -254,7 +254,6 @@ public class TestMultiTermConstantScore extends BaseTestRangeFilter {
|
|||
Query q1 = new BoostQuery(csrq("data", "A", "A", T, T), .1f); // matches document #0
|
||||
Query q2 = csrq("data", "Z", "Z", T, T); // matches document #1
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(q1, BooleanClause.Occur.SHOULD);
|
||||
bq.add(q2, BooleanClause.Occur.SHOULD);
|
||||
|
||||
|
@ -266,7 +265,6 @@ public class TestMultiTermConstantScore extends BaseTestRangeFilter {
|
|||
q1 = new BoostQuery(csrq("data", "A", "A", T, T, MultiTermQuery.CONSTANT_SCORE_BOOLEAN_REWRITE), .1f); // matches document #0
|
||||
q2 = csrq("data", "Z", "Z", T, T, MultiTermQuery.CONSTANT_SCORE_BOOLEAN_REWRITE); // matches document #1
|
||||
bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(q1, BooleanClause.Occur.SHOULD);
|
||||
bq.add(q2, BooleanClause.Occur.SHOULD);
|
||||
|
||||
|
|
|
@ -41,8 +41,6 @@ public class TestSimilarity extends LuceneTestCase {
|
|||
public static class SimpleSimilarity extends ClassicSimilarity {
|
||||
@Override
|
||||
public float queryNorm(float sumOfSquaredWeights) { return 1.0f; }
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) { return 1.0f; }
|
||||
@Override public float lengthNorm(FieldInvertState state) { return state.getBoost(); }
|
||||
@Override public float tf(float freq) { return freq; }
|
||||
@Override public float sloppyFreq(int distance) { return 2.0f; }
|
||||
|
|
|
@ -113,11 +113,6 @@ public class TestSimilarityProvider extends LuceneTestCase {
|
|||
public float decodeNormValue(long norm) {
|
||||
return norm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return 1f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float queryNorm(float sumOfSquaredWeights) {
|
||||
|
@ -161,11 +156,6 @@ public class TestSimilarityProvider extends LuceneTestCase {
|
|||
public float decodeNormValue(long norm) {
|
||||
return norm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return 1f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float queryNorm(float sumOfSquaredWeights) {
|
||||
|
|
|
@ -297,7 +297,6 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
outerQuery.add(new TermQuery(new Term(FIELD, "w1")), BooleanClause.Occur.MUST);
|
||||
|
||||
BooleanQuery.Builder innerQuery = new BooleanQuery.Builder();
|
||||
innerQuery.setDisableCoord(random().nextBoolean());
|
||||
innerQuery.add(new TermQuery(new Term(FIELD, "qq")), BooleanClause.Occur.SHOULD);
|
||||
|
||||
BooleanQuery.Builder childLeft = new BooleanQuery.Builder();
|
||||
|
@ -319,7 +318,6 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
outerQuery.add(new TermQuery(new Term(FIELD, "w1")), BooleanClause.Occur.MUST);
|
||||
|
||||
BooleanQuery.Builder innerQuery = new BooleanQuery.Builder();
|
||||
innerQuery.setDisableCoord(random().nextBoolean());
|
||||
innerQuery.add(new TermQuery(new Term(FIELD, "qq")), BooleanClause.Occur.SHOULD);
|
||||
|
||||
BooleanQuery.Builder childLeft = new BooleanQuery.Builder();
|
||||
|
@ -341,7 +339,6 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
outerQuery.add(new TermQuery(new Term(FIELD, "w1")), BooleanClause.Occur.MUST);
|
||||
|
||||
BooleanQuery.Builder innerQuery = new BooleanQuery.Builder();
|
||||
innerQuery.setDisableCoord(random().nextBoolean());
|
||||
innerQuery.add(new TermQuery(new Term(FIELD, "qq")), BooleanClause.Occur.SHOULD);
|
||||
|
||||
BooleanQuery.Builder childLeft = new BooleanQuery.Builder();
|
||||
|
@ -363,7 +360,6 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
outerQuery.add(new TermQuery(new Term(FIELD, "w1")), BooleanClause.Occur.MUST);
|
||||
|
||||
BooleanQuery.Builder innerQuery = new BooleanQuery.Builder();
|
||||
innerQuery.setDisableCoord(random().nextBoolean());
|
||||
innerQuery.add(new TermQuery(new Term(FIELD, "qq")), BooleanClause.Occur.SHOULD);
|
||||
|
||||
BooleanQuery.Builder childLeft = new BooleanQuery.Builder();
|
||||
|
@ -382,7 +378,6 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
}
|
||||
public void testBQ11() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(FIELD, "w1")), BooleanClause.Occur.SHOULD);
|
||||
TermQuery boostedQuery = new TermQuery(new Term(FIELD, "w1"));
|
||||
query.add(new BoostQuery(boostedQuery, 1000), BooleanClause.Occur.SHOULD);
|
||||
|
@ -391,21 +386,18 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
}
|
||||
public void testBQ14() throws Exception {
|
||||
BooleanQuery.Builder q = new BooleanQuery.Builder();
|
||||
q.setDisableCoord(random().nextBoolean());
|
||||
q.add(new TermQuery(new Term(FIELD, "QQQQQ")), BooleanClause.Occur.SHOULD);
|
||||
q.add(new TermQuery(new Term(FIELD, "w1")), BooleanClause.Occur.SHOULD);
|
||||
qtest(q.build(), new int[] { 0,1,2,3 });
|
||||
}
|
||||
public void testBQ15() throws Exception {
|
||||
BooleanQuery.Builder q = new BooleanQuery.Builder();
|
||||
q.setDisableCoord(random().nextBoolean());
|
||||
q.add(new TermQuery(new Term(FIELD, "QQQQQ")), BooleanClause.Occur.MUST_NOT);
|
||||
q.add(new TermQuery(new Term(FIELD, "w1")), BooleanClause.Occur.SHOULD);
|
||||
qtest(q.build(), new int[] { 0,1,2,3 });
|
||||
}
|
||||
public void testBQ16() throws Exception {
|
||||
BooleanQuery.Builder q = new BooleanQuery.Builder();
|
||||
q.setDisableCoord(random().nextBoolean());
|
||||
q.add(new TermQuery(new Term(FIELD, "QQQQQ")), BooleanClause.Occur.SHOULD);
|
||||
|
||||
BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();
|
||||
|
@ -417,7 +409,6 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
}
|
||||
public void testBQ17() throws Exception {
|
||||
BooleanQuery.Builder q = new BooleanQuery.Builder();
|
||||
q.setDisableCoord(random().nextBoolean());
|
||||
q.add(new TermQuery(new Term(FIELD, "w2")), BooleanClause.Occur.SHOULD);
|
||||
|
||||
BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();
|
||||
|
@ -437,7 +428,6 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
|
||||
public void testBQ20() throws Exception {
|
||||
BooleanQuery.Builder q = new BooleanQuery.Builder();
|
||||
q.setDisableCoord(random().nextBoolean());
|
||||
q.setMinimumNumberShouldMatch(2);
|
||||
q.add(new TermQuery(new Term(FIELD, "QQQQQ")), BooleanClause.Occur.SHOULD);
|
||||
q.add(new TermQuery(new Term(FIELD, "yy")), BooleanClause.Occur.SHOULD);
|
||||
|
@ -451,7 +441,6 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
|
||||
public void testBQ21() throws Exception {
|
||||
BooleanQuery.Builder q = new BooleanQuery.Builder();
|
||||
q.setDisableCoord(random().nextBoolean());
|
||||
q.add(new TermQuery(new Term(FIELD, "yy")), BooleanClause.Occur.SHOULD);
|
||||
q.add(new TermQuery(new Term(FIELD, "zz")), BooleanClause.Occur.SHOULD);
|
||||
|
||||
|
@ -505,7 +494,6 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
}
|
||||
public void testMultiFieldBQ3() throws Exception {
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(random().nextBoolean());
|
||||
query.add(new TermQuery(new Term(FIELD, "yy")), BooleanClause.Occur.SHOULD);
|
||||
query.add(new TermQuery(new Term(ALTFIELD, "w3")), BooleanClause.Occur.MUST);
|
||||
|
||||
|
@ -513,7 +501,6 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
}
|
||||
public void testMultiFieldBQ4() throws Exception {
|
||||
BooleanQuery.Builder outerQuery = new BooleanQuery.Builder();
|
||||
outerQuery.setDisableCoord(random().nextBoolean());
|
||||
outerQuery.add(new TermQuery(new Term(FIELD, "w1")), BooleanClause.Occur.SHOULD);
|
||||
|
||||
BooleanQuery.Builder innerQuery = new BooleanQuery.Builder();
|
||||
|
@ -525,7 +512,6 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
}
|
||||
public void testMultiFieldBQ5() throws Exception {
|
||||
BooleanQuery.Builder outerQuery = new BooleanQuery.Builder();
|
||||
outerQuery.setDisableCoord(random().nextBoolean());
|
||||
outerQuery.add(new TermQuery(new Term(FIELD, "w1")), BooleanClause.Occur.SHOULD);
|
||||
|
||||
BooleanQuery.Builder innerQuery = new BooleanQuery.Builder();
|
||||
|
|
|
@ -109,7 +109,6 @@ public class TestSimilarity2 extends LuceneTestCase {
|
|||
for (Similarity sim : sims) {
|
||||
is.setSimilarity(sim);
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(true);
|
||||
query.add(new TermQuery(new Term("foo", "bar")), BooleanClause.Occur.SHOULD);
|
||||
query.add(new TermQuery(new Term("bar", "baz")), BooleanClause.Occur.SHOULD);
|
||||
assertEquals(1, is.search(query.build(), 10).totalHits);
|
||||
|
@ -132,7 +131,6 @@ public class TestSimilarity2 extends LuceneTestCase {
|
|||
for (Similarity sim : sims) {
|
||||
is.setSimilarity(sim);
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(true);
|
||||
query.add(new TermQuery(new Term("foo", "bar")), BooleanClause.Occur.SHOULD);
|
||||
query.add(new TermQuery(new Term("foo", "baz")), BooleanClause.Occur.SHOULD);
|
||||
assertEquals(1, is.search(query.build(), 10).totalHits);
|
||||
|
@ -158,7 +156,6 @@ public class TestSimilarity2 extends LuceneTestCase {
|
|||
for (Similarity sim : sims) {
|
||||
is.setSimilarity(sim);
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(true);
|
||||
query.add(new TermQuery(new Term("foo", "bar")), BooleanClause.Occur.SHOULD);
|
||||
assertEquals(1, is.search(query.build(), 10).totalHits);
|
||||
}
|
||||
|
@ -230,7 +227,6 @@ public class TestSimilarity2 extends LuceneTestCase {
|
|||
for (Similarity sim : sims) {
|
||||
is.setSimilarity(sim);
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(true);
|
||||
query.add(new TermQuery(new Term("foo", "bar")), BooleanClause.Occur.SHOULD);
|
||||
assertEquals(1, is.search(query.build(), 10).totalHits);
|
||||
}
|
||||
|
@ -257,7 +253,6 @@ public class TestSimilarity2 extends LuceneTestCase {
|
|||
for (Similarity sim : sims) {
|
||||
is.setSimilarity(sim);
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(true);
|
||||
query.add(new TermQuery(new Term("foo", "bar")), BooleanClause.Occur.SHOULD);
|
||||
assertEquals(1, is.search(query.build(), 10).totalHits);
|
||||
}
|
||||
|
|
|
@ -108,7 +108,6 @@ public final class DrillDownQuery extends Query {
|
|||
if (drillDownDims.containsKey(dim) == false) {
|
||||
drillDownDims.put(dim, drillDownDims.size());
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.setDisableCoord(true);
|
||||
dimQueries.add(builder);
|
||||
}
|
||||
final int index = drillDownDims.get(dim);
|
||||
|
|
|
@ -1132,7 +1132,6 @@ public class TestDrillSideways extends FacetTestCase {
|
|||
DrillSideways ds = new DrillSideways(searcher, config, taxoReader);
|
||||
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(new TermQuery(new Term("field", "foo")), BooleanClause.Occur.MUST);
|
||||
bq.add(new TermQuery(new Term("field", "bar")), BooleanClause.Occur.MUST_NOT);
|
||||
DrillDownQuery ddq = new DrillDownQuery(config, bq.build());
|
||||
|
|
|
@ -35,7 +35,6 @@ import org.apache.lucene.search.BoostQuery;
|
|||
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.search.similarities.Similarity;
|
||||
|
||||
/**
|
||||
* A query that executes high-frequency terms in a optional sub-query to prevent
|
||||
|
@ -43,10 +42,7 @@ import org.apache.lucene.search.similarities.Similarity;
|
|||
* builds 2 queries off the {@link #add(Term) added} terms: low-frequency
|
||||
* terms are added to a required boolean clause and high-frequency terms are
|
||||
* added to an optional boolean clause. The optional clause is only executed if
|
||||
* the required "low-frequency" clause matches. Scores produced by this query
|
||||
* will be slightly different than plain {@link BooleanQuery} scorer mainly due to
|
||||
* differences in the {@link Similarity#coord(int,int) number of leaf queries}
|
||||
* in the required boolean clause. In most cases, high-frequency terms are
|
||||
* the required "low-frequency" clause matches. In most cases, high-frequency terms are
|
||||
* unlikely to significantly contribute to the document score unless at least
|
||||
* one of the low-frequency terms are matched. This query can improve
|
||||
* query execution times significantly if applicable.
|
||||
|
@ -69,7 +65,6 @@ public class CommonTermsQuery extends Query {
|
|||
* to do so.
|
||||
*/
|
||||
protected final List<Term> terms = new ArrayList<>();
|
||||
protected final boolean disableCoord;
|
||||
protected final float maxTermFrequency;
|
||||
protected final Occur lowFreqOccur;
|
||||
protected final Occur highFreqOccur;
|
||||
|
@ -95,29 +90,6 @@ public class CommonTermsQuery extends Query {
|
|||
*/
|
||||
public CommonTermsQuery(Occur highFreqOccur, Occur lowFreqOccur,
|
||||
float maxTermFrequency) {
|
||||
this(highFreqOccur, lowFreqOccur, maxTermFrequency, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link CommonTermsQuery}
|
||||
*
|
||||
* @param highFreqOccur
|
||||
* {@link Occur} used for high frequency terms
|
||||
* @param lowFreqOccur
|
||||
* {@link Occur} used for low frequency terms
|
||||
* @param maxTermFrequency
|
||||
* a value in [0..1) (or absolute number >=1) representing the
|
||||
* maximum threshold of a terms document frequency to be considered a
|
||||
* low frequency term.
|
||||
* @param disableCoord
|
||||
* disables {@link Similarity#coord(int,int)} in scoring for the low
|
||||
* / high frequency sub-queries
|
||||
* @throws IllegalArgumentException
|
||||
* if {@link Occur#MUST_NOT} is pass as lowFreqOccur or
|
||||
* highFreqOccur
|
||||
*/
|
||||
public CommonTermsQuery(Occur highFreqOccur, Occur lowFreqOccur,
|
||||
float maxTermFrequency, boolean disableCoord) {
|
||||
if (highFreqOccur == Occur.MUST_NOT) {
|
||||
throw new IllegalArgumentException(
|
||||
"highFreqOccur should be MUST or SHOULD but was MUST_NOT");
|
||||
|
@ -126,7 +98,6 @@ public class CommonTermsQuery extends Query {
|
|||
throw new IllegalArgumentException(
|
||||
"lowFreqOccur should be MUST or SHOULD but was MUST_NOT");
|
||||
}
|
||||
this.disableCoord = disableCoord;
|
||||
this.highFreqOccur = highFreqOccur;
|
||||
this.lowFreqOccur = lowFreqOccur;
|
||||
this.maxTermFrequency = maxTermFrequency;
|
||||
|
@ -216,11 +187,9 @@ public class CommonTermsQuery extends Query {
|
|||
}
|
||||
}
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.setDisableCoord(true);
|
||||
|
||||
if (lowFreqQueries.isEmpty() == false) {
|
||||
BooleanQuery.Builder lowFreq = new BooleanQuery.Builder();
|
||||
lowFreq.setDisableCoord(disableCoord);
|
||||
for (Query query : lowFreqQueries) {
|
||||
lowFreq.add(query, lowFreqOccur);
|
||||
}
|
||||
|
@ -230,7 +199,6 @@ public class CommonTermsQuery extends Query {
|
|||
}
|
||||
if (highFreqQueries.isEmpty() == false) {
|
||||
BooleanQuery.Builder highFreq = new BooleanQuery.Builder();
|
||||
highFreq.setDisableCoord(disableCoord);
|
||||
for (Query query : highFreqQueries) {
|
||||
highFreq.add(query, highFreqOccur);
|
||||
}
|
||||
|
@ -275,15 +243,6 @@ public class CommonTermsQuery extends Query {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff {@link Similarity#coord(int,int)} is disabled in scoring
|
||||
* for the high and low frequency query instance. The top level query will
|
||||
* always disable coords.
|
||||
*/
|
||||
public boolean isCoordDisabled() {
|
||||
return disableCoord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a minimum number of the low frequent optional BooleanClauses which must be
|
||||
* satisfied in order to produce a match on the low frequency terms query
|
||||
|
@ -413,7 +372,6 @@ public class CommonTermsQuery extends Query {
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = classHash();
|
||||
result = prime * result + (disableCoord ? 1231 : 1237);
|
||||
result = prime * result + Float.floatToIntBits(highFreqBoost);
|
||||
result = prime * result + Objects.hashCode(highFreqOccur);
|
||||
result = prime * result + Objects.hashCode(lowFreqOccur);
|
||||
|
@ -432,8 +390,7 @@ public class CommonTermsQuery extends Query {
|
|||
}
|
||||
|
||||
private boolean equalsTo(CommonTermsQuery other) {
|
||||
return disableCoord == other.disableCoord &&
|
||||
Float.floatToIntBits(highFreqBoost) == Float.floatToIntBits(other.highFreqBoost) &&
|
||||
return Float.floatToIntBits(highFreqBoost) == Float.floatToIntBits(other.highFreqBoost) &&
|
||||
highFreqOccur == other.highFreqOccur &&
|
||||
lowFreqOccur == other.lowFreqOccur &&
|
||||
Float.floatToIntBits(lowFreqBoost) == Float.floatToIntBits(other.lowFreqBoost) &&
|
||||
|
|
|
@ -69,7 +69,6 @@ public class MoreLikeThisQuery extends Query {
|
|||
mlt.setStopWords(stopWords);
|
||||
BooleanQuery bq = (BooleanQuery) mlt.like(fieldName, new StringReader(likeText));
|
||||
BooleanQuery.Builder newBq = new BooleanQuery.Builder();
|
||||
newBq.setDisableCoord(bq.isCoordDisabled());
|
||||
for (BooleanClause clause : bq) {
|
||||
newBq.add(clause);
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ public class CommonTermsQueryTest extends LuceneTestCase {
|
|||
|
||||
public void testEqualsHashCode() {
|
||||
CommonTermsQuery query = new CommonTermsQuery(randomOccur(random()),
|
||||
randomOccur(random()), random().nextFloat(), random().nextBoolean());
|
||||
randomOccur(random()), random().nextFloat());
|
||||
int terms = atLeast(2);
|
||||
for (int i = 0; i < terms; i++) {
|
||||
query.add(new Term(TestUtil.randomRealisticUnicodeString(random()),
|
||||
|
@ -140,14 +140,14 @@ public class CommonTermsQueryTest extends LuceneTestCase {
|
|||
}
|
||||
QueryUtils.checkHashEquals(query);
|
||||
QueryUtils.checkUnequal(new CommonTermsQuery(randomOccur(random()),
|
||||
randomOccur(random()), random().nextFloat(), random().nextBoolean()),
|
||||
randomOccur(random()), random().nextFloat()),
|
||||
query);
|
||||
|
||||
{
|
||||
final long seed = random().nextLong();
|
||||
Random r = new Random(seed);
|
||||
CommonTermsQuery left = new CommonTermsQuery(randomOccur(r),
|
||||
randomOccur(r), r.nextFloat(), r.nextBoolean());
|
||||
randomOccur(r), r.nextFloat());
|
||||
int leftTerms = atLeast(r, 2);
|
||||
for (int i = 0; i < leftTerms; i++) {
|
||||
left.add(new Term(TestUtil.randomRealisticUnicodeString(r), TestUtil
|
||||
|
@ -158,7 +158,7 @@ public class CommonTermsQueryTest extends LuceneTestCase {
|
|||
|
||||
r = new Random(seed);
|
||||
CommonTermsQuery right = new CommonTermsQuery(randomOccur(r),
|
||||
randomOccur(r), r.nextFloat(), r.nextBoolean());
|
||||
randomOccur(r), r.nextFloat());
|
||||
int rightTerms = atLeast(r, 2);
|
||||
for (int i = 0; i < rightTerms; i++) {
|
||||
right.add(new Term(TestUtil.randomRealisticUnicodeString(r), TestUtil
|
||||
|
@ -453,7 +453,7 @@ public class CommonTermsQueryTest extends LuceneTestCase {
|
|||
Occur lowFreqOccur = randomOccur(random());
|
||||
BooleanQuery.Builder verifyQuery = new BooleanQuery.Builder();
|
||||
CommonTermsQuery cq = new CommonTermsQuery(randomOccur(random()),
|
||||
lowFreqOccur, highFreq - 1, random().nextBoolean());
|
||||
lowFreqOccur, highFreq - 1);
|
||||
for (TermAndFreq termAndFreq : lowTerms) {
|
||||
cq.add(new Term(field, termAndFreq.term));
|
||||
verifyQuery.add(new BooleanClause(new TermQuery(new Term(field,
|
||||
|
|
|
@ -234,7 +234,6 @@ public class TestCustomScoreQuery extends FunctionTestSetup {
|
|||
|
||||
// custom query, that should score the same as q1.
|
||||
BooleanQuery.Builder q2CustomNeutralB = new BooleanQuery.Builder();
|
||||
q2CustomNeutralB.setDisableCoord(true);
|
||||
Query q2CustomNeutralInner = new CustomScoreQuery(q1);
|
||||
q2CustomNeutralB.add(new BoostQuery(q2CustomNeutralInner, (float)Math.sqrt(dboost)), BooleanClause.Occur.SHOULD);
|
||||
// a little tricky: we split the boost across an outer BQ and CustomScoreQuery
|
||||
|
|
|
@ -124,12 +124,6 @@ class PreciseClassicSimilarity extends TFIDFSimilarity {
|
|||
/** Sole constructor: parameter-free */
|
||||
public PreciseClassicSimilarity() {}
|
||||
|
||||
/** Implemented as <code>overlap / maxOverlap</code>. */
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return overlap / (float)maxOverlap;
|
||||
}
|
||||
|
||||
/** Implemented as <code>1/sqrt(sumOfSquaredWeights)</code>. */
|
||||
@Override
|
||||
public float queryNorm(float sumOfSquaredWeights) {
|
||||
|
|
|
@ -267,11 +267,6 @@ public class TestPayloadScoreQuery extends LuceneTestCase {
|
|||
return 1.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
//Make everything else 1 so we see the effect of the payload
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
|
|
@ -261,11 +261,6 @@ public class TestPayloadTermQuery extends LuceneTestCase {
|
|||
public float queryNorm(float sumOfSquaredWeights) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: Remove warning after API has been finalized
|
||||
@Override
|
||||
|
|
|
@ -281,7 +281,6 @@ public class MultiFieldQueryParser extends QueryParser
|
|||
return null; // all clause words were filtered away by the analyzer.
|
||||
}
|
||||
BooleanQuery.Builder query = newBooleanQuery();
|
||||
query.setDisableCoord(true);
|
||||
for (Query sub : queries) {
|
||||
query.add(sub, BooleanClause.Occur.SHOULD);
|
||||
}
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.flexible.standard.builders;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
|
||||
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
|
||||
import org.apache.lucene.queryparser.flexible.core.builders.QueryTreeBuilder;
|
||||
import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode.Modifier;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.StandardBooleanQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.parser.EscapeQuerySyntaxImpl;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.BooleanQuery.TooManyClauses;
|
||||
import org.apache.lucene.search.similarities.Similarity;
|
||||
|
||||
/**
|
||||
* This builder does the same as the {@link BooleanQueryNodeBuilder}, but this
|
||||
* considers if the built {@link BooleanQuery} should have its coord disabled or
|
||||
* not. <br>
|
||||
*
|
||||
* @see BooleanQueryNodeBuilder
|
||||
* @see BooleanQuery
|
||||
* @see Similarity#coord(int, int)
|
||||
*/
|
||||
public class StandardBooleanQueryNodeBuilder implements StandardQueryBuilder {
|
||||
|
||||
public StandardBooleanQueryNodeBuilder() {
|
||||
// empty constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public BooleanQuery build(QueryNode queryNode) throws QueryNodeException {
|
||||
StandardBooleanQueryNode booleanNode = (StandardBooleanQueryNode) queryNode;
|
||||
|
||||
BooleanQuery.Builder bQuery = new BooleanQuery.Builder();
|
||||
bQuery.setDisableCoord(booleanNode.isDisableCoord());
|
||||
List<QueryNode> children = booleanNode.getChildren();
|
||||
|
||||
if (children != null) {
|
||||
|
||||
for (QueryNode child : children) {
|
||||
Object obj = child.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
|
||||
|
||||
if (obj != null) {
|
||||
Query query = (Query) obj;
|
||||
|
||||
try {
|
||||
bQuery.add(query, getModifierValue(child));
|
||||
} catch (TooManyClauses ex) {
|
||||
|
||||
throw new QueryNodeException(new MessageImpl(
|
||||
QueryParserMessages.TOO_MANY_BOOLEAN_CLAUSES, BooleanQuery
|
||||
.getMaxClauseCount(), queryNode
|
||||
.toQueryString(new EscapeQuerySyntaxImpl())), ex);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return bQuery.build();
|
||||
|
||||
}
|
||||
|
||||
private static BooleanClause.Occur getModifierValue(QueryNode node) {
|
||||
|
||||
if (node instanceof ModifierQueryNode) {
|
||||
ModifierQueryNode mNode = ((ModifierQueryNode) node);
|
||||
Modifier modifier = mNode.getModifier();
|
||||
|
||||
if (Modifier.MOD_NONE.equals(modifier)) {
|
||||
return BooleanClause.Occur.SHOULD;
|
||||
|
||||
} else if (Modifier.MOD_NOT.equals(modifier)) {
|
||||
return BooleanClause.Occur.MUST_NOT;
|
||||
|
||||
} else {
|
||||
return BooleanClause.Occur.MUST;
|
||||
}
|
||||
}
|
||||
|
||||
return BooleanClause.Occur.SHOULD;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -37,7 +37,7 @@ import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericRangeQ
|
|||
import org.apache.lucene.queryparser.flexible.standard.nodes.PrefixWildcardQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.RegexpQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.StandardBooleanQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.SynonymQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.WildcardQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.processors.StandardQueryNodeProcessorPipeline;
|
||||
import org.apache.lucene.search.Query;
|
||||
|
@ -73,8 +73,8 @@ public class StandardQueryTreeBuilder extends QueryTreeBuilder implements
|
|||
setBuilder(TermRangeQueryNode.class, new TermRangeQueryNodeBuilder());
|
||||
setBuilder(RegexpQueryNode.class, new RegexpQueryNodeBuilder());
|
||||
setBuilder(SlopQueryNode.class, new SlopQueryNodeBuilder());
|
||||
setBuilder(StandardBooleanQueryNode.class,
|
||||
new StandardBooleanQueryNodeBuilder());
|
||||
setBuilder(SynonymQueryNode.class,
|
||||
new SynonymQueryNodeBuilder());
|
||||
setBuilder(MultiPhraseQueryNode.class, new MultiPhraseQueryNodeBuilder());
|
||||
setBuilder(MatchAllDocsQueryNode.class, new MatchAllDocsQueryNodeBuilder());
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.lucene.queryparser.flexible.standard.builders;
|
||||
|
||||
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
|
||||
import org.apache.lucene.queryparser.flexible.core.builders.QueryTreeBuilder;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.SynonymQueryNode;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
|
||||
/** Builer for {@link SynonymQueryNode}. */
|
||||
public class SynonymQueryNodeBuilder implements StandardQueryBuilder {
|
||||
|
||||
/** Sole constructor. */
|
||||
public SynonymQueryNodeBuilder() {}
|
||||
|
||||
@Override
|
||||
public Query build(QueryNode queryNode) throws QueryNodeException {
|
||||
// TODO: use SynonymQuery instead
|
||||
SynonymQueryNode node = (SynonymQueryNode) queryNode;
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
for (QueryNode child : node.getChildren()) {
|
||||
Object obj = child.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
|
||||
|
||||
if (obj != null) {
|
||||
Query query = (Query) obj;
|
||||
builder.add(query, Occur.SHOULD);
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
|
@ -20,30 +20,11 @@ import java.util.List;
|
|||
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.BooleanQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.similarities.Similarity;
|
||||
|
||||
/**
|
||||
* A {@link StandardBooleanQueryNode} has the same behavior as
|
||||
* {@link BooleanQueryNode}. It only indicates if the coord should be enabled or
|
||||
* not for this boolean query.
|
||||
*
|
||||
* @see Similarity#coord(int, int)
|
||||
* @see BooleanQuery
|
||||
*/
|
||||
public class StandardBooleanQueryNode extends BooleanQueryNode {
|
||||
|
||||
private boolean disableCoord;
|
||||
|
||||
public StandardBooleanQueryNode(List<QueryNode> clauses, boolean disableCoord) {
|
||||
/** {@link QueryNode} for clauses that are synonym of each other. */
|
||||
public class SynonymQueryNode extends BooleanQueryNode {
|
||||
/** Sole constructor. */
|
||||
public SynonymQueryNode(List<QueryNode> clauses) {
|
||||
super(clauses);
|
||||
|
||||
this.disableCoord = disableCoord;
|
||||
|
||||
}
|
||||
|
||||
public boolean isDisableCoord() {
|
||||
return this.disableCoord;
|
||||
}
|
||||
|
||||
}
|
|
@ -47,7 +47,7 @@ import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfi
|
|||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.Operator;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.MultiPhraseQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.RegexpQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.StandardBooleanQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.SynonymQueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.WildcardQueryNode;
|
||||
|
||||
/**
|
||||
|
@ -209,10 +209,10 @@ public class AnalyzerQueryNodeProcessor extends QueryNodeProcessorImpl {
|
|||
|
||||
}
|
||||
return new GroupQueryNode(
|
||||
new StandardBooleanQueryNode(children, positionCount==1));
|
||||
new SynonymQueryNode(children));
|
||||
} else {
|
||||
// multiple positions
|
||||
QueryNode q = new StandardBooleanQueryNode(Collections.<QueryNode>emptyList(),false);
|
||||
QueryNode q = new BooleanQueryNode(Collections.<QueryNode>emptyList());
|
||||
QueryNode currentQuery = null;
|
||||
for (int i = 0; i < numTokens; i++) {
|
||||
String term = null;
|
||||
|
@ -226,7 +226,7 @@ public class AnalyzerQueryNodeProcessor extends QueryNodeProcessorImpl {
|
|||
if (posIncrAtt != null && posIncrAtt.getPositionIncrement() == 0) {
|
||||
if (!(currentQuery instanceof BooleanQueryNode)) {
|
||||
QueryNode t = currentQuery;
|
||||
currentQuery = new StandardBooleanQueryNode(Collections.<QueryNode>emptyList(), true);
|
||||
currentQuery = new SynonymQueryNode(Collections.<QueryNode>emptyList());
|
||||
((BooleanQueryNode)currentQuery).add(t);
|
||||
}
|
||||
((BooleanQueryNode)currentQuery).add(new FieldQueryNode(field, term, -1, -1));
|
||||
|
|
|
@ -416,7 +416,6 @@ public class SimpleQueryParser extends QueryBuilder {
|
|||
|
||||
private static BooleanQuery addClause(BooleanQuery bq, Query query, BooleanClause.Occur occur) {
|
||||
BooleanQuery.Builder newBq = new BooleanQuery.Builder();
|
||||
newBq.setDisableCoord(bq.isCoordDisabled());
|
||||
newBq.setMinimumNumberShouldMatch(bq.getMinimumNumberShouldMatch());
|
||||
for (BooleanClause clause : bq) {
|
||||
newBq.add(clause);
|
||||
|
@ -530,7 +529,6 @@ public class SimpleQueryParser extends QueryBuilder {
|
|||
*/
|
||||
protected Query newDefaultQuery(String text) {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
for (Map.Entry<String,Float> entry : weights.entrySet()) {
|
||||
Query q = createBooleanQuery(entry.getKey(), text, defaultOperator);
|
||||
if (q != null) {
|
||||
|
@ -549,7 +547,6 @@ public class SimpleQueryParser extends QueryBuilder {
|
|||
*/
|
||||
protected Query newFuzzyQuery(String text, int fuzziness) {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
for (Map.Entry<String,Float> entry : weights.entrySet()) {
|
||||
Query q = new FuzzyQuery(new Term(entry.getKey(), text), fuzziness);
|
||||
float boost = entry.getValue();
|
||||
|
@ -566,7 +563,6 @@ public class SimpleQueryParser extends QueryBuilder {
|
|||
*/
|
||||
protected Query newPhraseQuery(String text, int slop) {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
for (Map.Entry<String,Float> entry : weights.entrySet()) {
|
||||
Query q = createPhraseQuery(entry.getKey(), text, slop);
|
||||
if (q != null) {
|
||||
|
@ -585,7 +581,6 @@ public class SimpleQueryParser extends QueryBuilder {
|
|||
*/
|
||||
protected Query newPrefixQuery(String text) {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
for (Map.Entry<String,Float> entry : weights.entrySet()) {
|
||||
Query q = new PrefixQuery(new Term(entry.getKey(), text));
|
||||
float boost = entry.getValue();
|
||||
|
|
|
@ -45,7 +45,6 @@ public class BooleanQueryBuilder implements QueryBuilder {
|
|||
@Override
|
||||
public Query getQuery(Element e) throws ParserException {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(DOMUtils.getAttribute(e, "disableCoord", false));
|
||||
bq.setMinimumNumberShouldMatch(DOMUtils.getAttribute(e, "minimumNumberShouldMatch", 0));
|
||||
|
||||
NodeList nl = e.getChildNodes();
|
||||
|
|
|
@ -50,7 +50,6 @@ public class TermsQueryBuilder implements QueryBuilder {
|
|||
String text = DOMUtils.getNonBlankTextOrFail(e);
|
||||
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(DOMUtils.getAttribute(e, "disableCoord", false));
|
||||
bq.setMinimumNumberShouldMatch(DOMUtils.getAttribute(e, "minimumNumberShouldMatch", 0));
|
||||
try (TokenStream ts = analyzer.tokenStream(fieldName, text)) {
|
||||
TermToBytesRefAttribute termAtt = ts.addAttribute(TermToBytesRefAttribute.class);
|
||||
|
|
|
@ -326,7 +326,6 @@ public class TestMultiFieldQueryParser extends LuceneTestCase {
|
|||
MultiFieldQueryParser mfqp = new MultiFieldQueryParser(fields, new MockAnalyzer(random()));
|
||||
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(new RegexpQuery(new Term("a", "[a-z][123]")), Occur.SHOULD);
|
||||
bq.add(new RegexpQuery(new Term("b", "[a-z][123]")), Occur.SHOULD);
|
||||
assertEquals(bq.build(), mfqp.parse("/[a-z][123]/"));
|
||||
|
|
|
@ -188,7 +188,6 @@ public class TestStandardQP extends QueryParserTestBase {
|
|||
/** ordinary behavior, synonyms form uncoordinated boolean query */
|
||||
StandardQueryParser dumb = getParser(new Analyzer1());
|
||||
BooleanQuery.Builder expanded = new BooleanQuery.Builder();
|
||||
expanded.setDisableCoord(true);
|
||||
expanded.add(new TermQuery(new Term("field", "dogs")),
|
||||
BooleanClause.Occur.SHOULD);
|
||||
expanded.add(new TermQuery(new Term("field", "dog")),
|
||||
|
|
|
@ -477,7 +477,6 @@ public class TestSimpleQueryParser extends LuceneTestCase {
|
|||
weights.put("field1", 10f);
|
||||
|
||||
BooleanQuery.Builder expected = new BooleanQuery.Builder();
|
||||
expected.setDisableCoord(true);
|
||||
Query field0 = new TermQuery(new Term("field0", "foo"));
|
||||
field0 = new BoostQuery(field0, 5f);
|
||||
expected.add(field0, Occur.SHOULD);
|
||||
|
@ -498,7 +497,6 @@ public class TestSimpleQueryParser extends LuceneTestCase {
|
|||
|
||||
BooleanQuery.Builder expected = new BooleanQuery.Builder();
|
||||
BooleanQuery.Builder foo = new BooleanQuery.Builder();
|
||||
foo.setDisableCoord(true);
|
||||
Query field0 = new TermQuery(new Term("field0", "foo"));
|
||||
field0 = new BoostQuery(field0, 5f);
|
||||
foo.add(field0, Occur.SHOULD);
|
||||
|
@ -508,7 +506,6 @@ public class TestSimpleQueryParser extends LuceneTestCase {
|
|||
expected.add(foo.build(), Occur.SHOULD);
|
||||
|
||||
BooleanQuery.Builder bar = new BooleanQuery.Builder();
|
||||
bar.setDisableCoord(true);
|
||||
field0 = new TermQuery(new Term("field0", "bar"));
|
||||
field0 = new BoostQuery(field0, 5f);
|
||||
bar.add(field0, Occur.SHOULD);
|
||||
|
|
|
@ -208,7 +208,6 @@ public class LatLonPoint extends Field {
|
|||
if (maxLongitude < minLongitude) {
|
||||
// Disable coord here because a multi-valued doc could match both rects and get unfairly boosted:
|
||||
BooleanQuery.Builder q = new BooleanQuery.Builder();
|
||||
q.setDisableCoord(true);
|
||||
|
||||
// E.g.: maxLon = -179, minLon = 179
|
||||
byte[] leftOpen = lower.clone();
|
||||
|
|
|
@ -308,7 +308,6 @@ public class FuzzyLikeThisQuery extends Query
|
|||
else
|
||||
{
|
||||
BooleanQuery.Builder termVariants=new BooleanQuery.Builder();
|
||||
termVariants.setDisableCoord(true); //disable coord and IDF for these term variants
|
||||
for (Iterator<ScoreTerm> iterator2 = variants.iterator(); iterator2
|
||||
.hasNext();)
|
||||
{
|
||||
|
|
|
@ -100,13 +100,11 @@ public abstract class BaseExplanationTestCase extends LuceneTestCase {
|
|||
|
||||
/**
|
||||
* check the expDocNrs match and have scores that match the explanations.
|
||||
* Query may be randomly wrapped in a BooleanQuery with a term that matches no documents in
|
||||
* order to trigger coord logic.
|
||||
* Query may be randomly wrapped in a BooleanQuery with a term that matches no documents.
|
||||
*/
|
||||
public void qtest(Query q, int[] expDocNrs) throws Exception {
|
||||
if (random().nextBoolean()) {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(random().nextBoolean());
|
||||
bq.add(q, BooleanClause.Occur.SHOULD);
|
||||
bq.add(new TermQuery(new Term("NEVER","MATCH")), BooleanClause.Occur.SHOULD);
|
||||
q = bq.build();
|
||||
|
@ -214,7 +212,6 @@ public abstract class BaseExplanationTestCase extends LuceneTestCase {
|
|||
*/
|
||||
public Query optB(Query q) throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(q, BooleanClause.Occur.SHOULD);
|
||||
bq.add(new TermQuery(new Term("NEVER","MATCH")), BooleanClause.Occur.MUST_NOT);
|
||||
return bq.build();
|
||||
|
@ -226,7 +223,6 @@ public abstract class BaseExplanationTestCase extends LuceneTestCase {
|
|||
*/
|
||||
public Query reqB(Query q) throws Exception {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
bq.add(q, BooleanClause.Occur.MUST);
|
||||
bq.add(new TermQuery(new Term(FIELD,"w1")), BooleanClause.Occur.SHOULD);
|
||||
return bq.build();
|
||||
|
|
|
@ -35,28 +35,15 @@ public class RandomSimilarity extends PerFieldSimilarityWrapper {
|
|||
final List<Similarity> knownSims;
|
||||
Map<String,Similarity> previousMappings = new HashMap<>();
|
||||
final int perFieldSeed;
|
||||
final int coordType; // 0 = no coord, 1 = coord, 2 = crazy coord
|
||||
final boolean shouldQueryNorm;
|
||||
|
||||
public RandomSimilarity(Random random) {
|
||||
perFieldSeed = random.nextInt();
|
||||
coordType = random.nextInt(3);
|
||||
shouldQueryNorm = random.nextBoolean();
|
||||
knownSims = new ArrayList<>(allSims);
|
||||
Collections.shuffle(knownSims, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float coord(int overlap, int maxOverlap) {
|
||||
if (coordType == 0) {
|
||||
return 1.0f;
|
||||
} else if (coordType == 1) {
|
||||
return defaultSim.coord(overlap, maxOverlap);
|
||||
} else {
|
||||
return overlap / ((float)maxOverlap + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float queryNorm(float sumOfSquaredWeights) {
|
||||
if (shouldQueryNorm) {
|
||||
|
@ -138,14 +125,6 @@ public class RandomSimilarity extends PerFieldSimilarityWrapper {
|
|||
|
||||
@Override
|
||||
public synchronized String toString() {
|
||||
final String coordMethod;
|
||||
if (coordType == 0) {
|
||||
coordMethod = "no";
|
||||
} else if (coordType == 1) {
|
||||
coordMethod = "yes";
|
||||
} else {
|
||||
coordMethod = "crazy";
|
||||
}
|
||||
return "RandomSimilarity(queryNorm=" + shouldQueryNorm + ",coord=" + coordMethod + "): " + previousMappings.toString();
|
||||
return "RandomSimilarity(queryNorm=" + shouldQueryNorm + "): " + previousMappings.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -360,7 +360,6 @@ public class MoreLikeThisHandler extends RequestHandlerBase
|
|||
BooleanQuery boostedQuery = (BooleanQuery)mltquery;
|
||||
if (boostFields.size() > 0) {
|
||||
BooleanQuery.Builder newQ = new BooleanQuery.Builder();
|
||||
newQ.setDisableCoord(boostedQuery.isCoordDisabled());
|
||||
newQ.setMinimumNumberShouldMatch(boostedQuery.getMinimumNumberShouldMatch());
|
||||
for (BooleanClause clause : boostedQuery) {
|
||||
Query q = clause.getQuery();
|
||||
|
|
|
@ -423,7 +423,6 @@ public class QueryElevationComponent extends SearchComponent implements SolrCore
|
|||
rb.setQuery(new BoostQuery(booster.include, 0f));
|
||||
} else {
|
||||
BooleanQuery.Builder newq = new BooleanQuery.Builder();
|
||||
newq.setDisableCoord(true);
|
||||
newq.add(query, BooleanClause.Occur.SHOULD);
|
||||
newq.add(new BoostQuery(booster.include, 0f), BooleanClause.Occur.SHOULD);
|
||||
if (booster.exclude != null) {
|
||||
|
|
|
@ -98,7 +98,6 @@ public class LatLonType extends AbstractSubTypeFieldType implements SpatialQuery
|
|||
SchemaField latSF = subField(field, LAT, parser.getReq().getSchema());
|
||||
SchemaField lonSF = subField(field, LON, parser.getReq().getSchema());
|
||||
BooleanQuery.Builder result = new BooleanQuery.Builder();
|
||||
result.setDisableCoord(true);
|
||||
// points must currently be ordered... should we support specifying any two opposite corner points?
|
||||
result.add(latSF.getType().getRangeQuery(parser, latSF,
|
||||
Double.toString(p1.getY()), Double.toString(p2.getY()), minInclusive, maxInclusive), BooleanClause.Occur.MUST);
|
||||
|
@ -114,7 +113,6 @@ public class LatLonType extends AbstractSubTypeFieldType implements SpatialQuery
|
|||
SchemaField latSF = subField(field, LAT, parser.getReq().getSchema());
|
||||
SchemaField lonSF = subField(field, LON, parser.getReq().getSchema());
|
||||
BooleanQuery.Builder result = new BooleanQuery.Builder();
|
||||
result.setDisableCoord(true);
|
||||
result.add(latSF.getType().getFieldQuery(parser, latSF,
|
||||
Double.toString(p1.getY())), BooleanClause.Occur.MUST);
|
||||
result.add(lonSF.getType().getFieldQuery(parser, lonSF,
|
||||
|
|
|
@ -137,7 +137,6 @@ public class PointType extends CoordinateFieldType implements SpatialQueryable {
|
|||
String[] p2 = parseCommaSeparatedList(part2, dimension);
|
||||
|
||||
BooleanQuery.Builder result = new BooleanQuery.Builder();
|
||||
result.setDisableCoord(true);
|
||||
for (int i = 0; i < dimension; i++) {
|
||||
SchemaField subSF = subField(field, i, schema);
|
||||
// points must currently be ordered... should we support specifying any two opposite corner points?
|
||||
|
@ -151,7 +150,6 @@ public class PointType extends CoordinateFieldType implements SpatialQueryable {
|
|||
String[] p1 = parseCommaSeparatedList(externalVal, dimension);
|
||||
//TODO: should we assert that p1.length == dimension?
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
for (int i = 0; i < dimension; i++) {
|
||||
SchemaField sf = subField(field, i, schema);
|
||||
Query tq = sf.getType().getFieldQuery(parser, sf, p1[i]);
|
||||
|
|
|
@ -107,7 +107,6 @@ public class DisMaxQParser extends QParser {
|
|||
* this query is an artificial construct
|
||||
*/
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(true);
|
||||
|
||||
boolean notBlank = addMainQuery(query, solrParams);
|
||||
if (!notBlank)
|
||||
|
|
|
@ -143,7 +143,6 @@ public class ExtendedDismaxQParser extends QParser {
|
|||
* this query is an artificial construct
|
||||
*/
|
||||
BooleanQuery.Builder query = new BooleanQuery.Builder();
|
||||
query.setDisableCoord(true);
|
||||
|
||||
/* * * Main User Query * * */
|
||||
parsedUserQuery = null;
|
||||
|
@ -978,7 +977,6 @@ public class ExtendedDismaxQParser extends QParser {
|
|||
}
|
||||
|
||||
boolean makeDismax=true;
|
||||
boolean disableCoord=true;
|
||||
boolean allowWildcard=true;
|
||||
int minClauseSize = 0; // minimum number of clauses per phrase query...
|
||||
// used when constructing boosting part of query via sloppy phrases
|
||||
|
@ -1159,9 +1157,7 @@ public class ExtendedDismaxQParser extends QParser {
|
|||
DisjunctionMaxQuery q = new DisjunctionMaxQuery(lst, a.tie);
|
||||
return q;
|
||||
} else {
|
||||
// should we disable coord?
|
||||
BooleanQuery.Builder q = new BooleanQuery.Builder();
|
||||
q.setDisableCoord(disableCoord);
|
||||
for (Query sub : lst) {
|
||||
q.add(sub, BooleanClause.Occur.SHOULD);
|
||||
}
|
||||
|
@ -1238,17 +1234,11 @@ public class ExtendedDismaxQParser extends QParser {
|
|||
case FIELD: // fallthrough
|
||||
case PHRASE:
|
||||
Query query = super.getFieldQuery(field, val, type == QType.PHRASE);
|
||||
// A BooleanQuery is only possible from getFieldQuery if it came from
|
||||
// a single whitespace separated term. In this case, check the coordination
|
||||
// factor on the query: if it's enabled, that means we aren't a set of synonyms
|
||||
// but instead multiple terms from one whitespace-separated term, we must
|
||||
// apply minShouldMatch here so that it works correctly with other things
|
||||
// like aliasing.
|
||||
// Boolean query on a whitespace-separated string
|
||||
// If these were synonyms we would have a SynonymQuery
|
||||
if (query instanceof BooleanQuery) {
|
||||
BooleanQuery bq = (BooleanQuery) query;
|
||||
if (!bq.isCoordDisabled()) {
|
||||
query = SolrPluginUtils.setMinShouldMatch(bq, minShouldMatch, false);
|
||||
}
|
||||
query = SolrPluginUtils.setMinShouldMatch(bq, minShouldMatch, false);
|
||||
}
|
||||
if (query instanceof PhraseQuery) {
|
||||
PhraseQuery pq = (PhraseQuery)query;
|
||||
|
|
|
@ -328,7 +328,7 @@ public class QueryParsing {
|
|||
BooleanQuery q = (BooleanQuery) query;
|
||||
boolean needParens = false;
|
||||
|
||||
if (q.getMinimumNumberShouldMatch() != 0 || q.isCoordDisabled() || (flags & (FLAG_IS_CLAUSE | FLAG_BOOSTED)) != 0 ) {
|
||||
if (q.getMinimumNumberShouldMatch() != 0 || (flags & (FLAG_IS_CLAUSE | FLAG_BOOSTED)) != 0 ) {
|
||||
needParens = true;
|
||||
}
|
||||
if (needParens) {
|
||||
|
@ -360,9 +360,6 @@ public class QueryParsing {
|
|||
out.append('~');
|
||||
out.append(Integer.toString(q.getMinimumNumberShouldMatch()));
|
||||
}
|
||||
if (q.isCoordDisabled()) {
|
||||
out.append("/no_coord");
|
||||
}
|
||||
|
||||
} else if (query instanceof PrefixQuery) {
|
||||
PrefixQuery q = (PrefixQuery) query;
|
||||
|
|
|
@ -88,7 +88,6 @@ public class QueryUtils {
|
|||
return negClause;
|
||||
} else {
|
||||
BooleanQuery.Builder newBqB = new BooleanQuery.Builder();
|
||||
newBqB.setDisableCoord(bq.isCoordDisabled());
|
||||
// ignore minNrShouldMatch... it doesn't make sense for a negative query
|
||||
|
||||
// the inverse of -a -b is a OR b
|
||||
|
@ -121,7 +120,6 @@ public class QueryUtils {
|
|||
}
|
||||
BooleanQuery bq = (BooleanQuery) q;
|
||||
BooleanQuery.Builder newBqB = new BooleanQuery.Builder();
|
||||
newBqB.setDisableCoord(bq.isCoordDisabled());
|
||||
newBqB.setMinimumNumberShouldMatch(bq.getMinimumNumberShouldMatch());
|
||||
for (BooleanClause clause : bq) {
|
||||
newBqB.add(clause);
|
||||
|
|
|
@ -182,7 +182,6 @@ public class SimpleQParserPlugin extends QParserPlugin {
|
|||
@Override
|
||||
protected Query newPrefixQuery(String text) {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
|
||||
for (Map.Entry<String, Float> entry : weights.entrySet()) {
|
||||
String field = entry.getKey();
|
||||
|
@ -214,7 +213,6 @@ public class SimpleQParserPlugin extends QParserPlugin {
|
|||
@Override
|
||||
protected Query newFuzzyQuery(String text, int fuzziness) {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
|
||||
for (Map.Entry<String, Float> entry : weights.entrySet()) {
|
||||
String field = entry.getKey();
|
||||
|
|
|
@ -67,7 +67,6 @@ public class TermsQParserPlugin extends QParserPlugin {
|
|||
@Override
|
||||
Filter makeFilter(String fname, BytesRef[] byteRefs) {
|
||||
BooleanQuery.Builder bq = new BooleanQuery.Builder();
|
||||
bq.setDisableCoord(true);
|
||||
for (BytesRef byteRef : byteRefs) {
|
||||
bq.add(new TermQuery(new Term(fname, byteRef)), BooleanClause.Occur.SHOULD);
|
||||
}
|
||||
|
|
|
@ -139,7 +139,6 @@ public class CloudMLTQParser extends QParser {
|
|||
|
||||
if (boostFields.size() > 0) {
|
||||
BooleanQuery.Builder newQ = new BooleanQuery.Builder();
|
||||
newQ.setDisableCoord(boostedMLTQuery.isCoordDisabled());
|
||||
newQ.setMinimumNumberShouldMatch(boostedMLTQuery.getMinimumNumberShouldMatch());
|
||||
|
||||
for (BooleanClause clause : boostedMLTQuery) {
|
||||
|
@ -160,7 +159,6 @@ public class CloudMLTQParser extends QParser {
|
|||
|
||||
// exclude current document from results
|
||||
BooleanQuery.Builder realMLTQuery = new BooleanQuery.Builder();
|
||||
realMLTQuery.setDisableCoord(true);
|
||||
realMLTQuery.add(boostedMLTQuery, BooleanClause.Occur.MUST);
|
||||
realMLTQuery.add(createIdQuery(req.getSchema().getUniqueKeyField().getName(), id), BooleanClause.Occur.MUST_NOT);
|
||||
|
||||
|
|
|
@ -130,7 +130,6 @@ public class SimpleMLTQParser extends QParser {
|
|||
|
||||
if (boostFields.size() > 0) {
|
||||
BooleanQuery.Builder newQ = new BooleanQuery.Builder();
|
||||
newQ.setDisableCoord(boostedMLTQuery.isCoordDisabled());
|
||||
newQ.setMinimumNumberShouldMatch(boostedMLTQuery.getMinimumNumberShouldMatch());
|
||||
|
||||
for (BooleanClause clause : boostedMLTQuery) {
|
||||
|
@ -151,7 +150,6 @@ public class SimpleMLTQParser extends QParser {
|
|||
|
||||
// exclude current document from results
|
||||
BooleanQuery.Builder realMLTQuery = new BooleanQuery.Builder();
|
||||
realMLTQuery.setDisableCoord(true);
|
||||
realMLTQuery.add(boostedMLTQuery, BooleanClause.Occur.MUST);
|
||||
realMLTQuery.add(docIdQuery, BooleanClause.Occur.MUST_NOT);
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ import org.apache.solr.util.plugin.SolrCoreAware;
|
|||
* with the behavior of explicitly configuring that same <code>Similarity</code> globally, because
|
||||
* of differences in how some multi-field / multi-clause behavior is defined in
|
||||
* <code>PerFieldSimilarityWrapper</code>. In particular please consider carefully the documentation
|
||||
* & implementation of {@link Similarity#coord} and {@link Similarity#queryNorm} in
|
||||
* & implementation of {@link Similarity#queryNorm} in
|
||||
* {@link ClassicSimilarity} compared to {@link PerFieldSimilarityWrapper}
|
||||
* </p>
|
||||
*
|
||||
|
|
|
@ -664,7 +664,6 @@ public class SolrPluginUtils {
|
|||
|
||||
public static BooleanQuery setMinShouldMatch(BooleanQuery q, String spec, boolean mmAutoRelax) {
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
builder.setDisableCoord(q.isCoordDisabled());
|
||||
for (BooleanClause clause : q) {
|
||||
builder.add(clause);
|
||||
}
|
||||
|
|
|
@ -138,8 +138,8 @@ public class CloudMLTQParserTest extends SolrCloudTestCase {
|
|||
assertArrayEquals(expectedIds, actualIds);
|
||||
|
||||
String[] expectedQueryStrings = new String[]{
|
||||
"(+(lowerfilt_u:bmw lowerfilt_u:usa) -id:3)/no_coord",
|
||||
"(+(lowerfilt_u:usa lowerfilt_u:bmw) -id:3)/no_coord"};
|
||||
"+(lowerfilt_u:bmw lowerfilt_u:usa) -id:3",
|
||||
"+(lowerfilt_u:usa lowerfilt_u:bmw) -id:3"};
|
||||
|
||||
String[] actualParsedQueries;
|
||||
if (queryResponse.getDebugMap().get("parsedquery") instanceof String) {
|
||||
|
|
Loading…
Reference in New Issue