mirror of https://github.com/apache/lucene.git
LUCENE-6531: Make PhraseQuery immutable.
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1685754 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8d8818fea1
commit
c397fe7234
|
@ -32,6 +32,9 @@ API Changes
|
|||
* LUCENE-6067: Accountable.getChildResources has a default
|
||||
implementation returning the empty list. (Robert Muir)
|
||||
|
||||
* LUCENE-6531: PhraseQuery is now immutable and can be built using the
|
||||
PhraseQuery.Builder class. (Adrien Grand)
|
||||
|
||||
======================= Lucene 5.3.0 =======================
|
||||
|
||||
New Features
|
||||
|
|
|
@ -36,7 +36,12 @@ import org.apache.lucene.index.IndexReader;
|
|||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.PhraseQuery;
|
||||
import org.apache.lucene.search.ScoreDoc;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.store.Directory;
|
||||
|
||||
/**
|
||||
|
@ -98,8 +103,7 @@ public class ShingleAnalyzerWrapperTest extends BaseTokenStreamTestCase {
|
|||
* This shows how to construct a phrase query containing shingles.
|
||||
*/
|
||||
public void testShingleAnalyzerWrapperPhraseQuery() throws Exception {
|
||||
PhraseQuery q = new PhraseQuery();
|
||||
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
try (TokenStream ts = analyzer.tokenStream("content", "this sentence")) {
|
||||
int j = -1;
|
||||
|
||||
|
@ -110,11 +114,12 @@ public class ShingleAnalyzerWrapperTest extends BaseTokenStreamTestCase {
|
|||
while (ts.incrementToken()) {
|
||||
j += posIncrAtt.getPositionIncrement();
|
||||
String termText = termAtt.toString();
|
||||
q.add(new Term("content", termText), j);
|
||||
builder.add(new Term("content", termText), j);
|
||||
}
|
||||
ts.end();
|
||||
}
|
||||
|
||||
PhraseQuery q = builder.build();
|
||||
ScoreDoc[] hits = searcher.search(q, 1000).scoreDocs;
|
||||
int[] ranks = new int[] { 0 };
|
||||
compareRanks(hits, ranks);
|
||||
|
|
|
@ -50,29 +50,31 @@ public class SimpleSloppyPhraseQueryMaker extends SimpleQueryMaker {
|
|||
for (int wd=0; wd<words.length-qlen-slop; wd++) {
|
||||
// ordered
|
||||
int remainedSlop = slop;
|
||||
PhraseQuery q = new PhraseQuery();
|
||||
q.setSlop(slop);
|
||||
int wind = wd;
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
for (int i=0; i<qlen; i++) {
|
||||
q.add(new Term(DocMaker.BODY_FIELD,words[wind++]));
|
||||
builder.add(new Term(DocMaker.BODY_FIELD, words[wind++]), i);
|
||||
if (remainedSlop>0) {
|
||||
remainedSlop--;
|
||||
wind++;
|
||||
}
|
||||
}
|
||||
builder.setSlop(slop);
|
||||
PhraseQuery q = builder.build();
|
||||
queries.add(q);
|
||||
// reversed
|
||||
remainedSlop = slop;
|
||||
q = new PhraseQuery();
|
||||
q.setSlop(slop+2*qlen);
|
||||
wind = wd+qlen+remainedSlop-1;
|
||||
builder = new PhraseQuery.Builder();
|
||||
for (int i=0; i<qlen; i++) {
|
||||
q.add(new Term(DocMaker.BODY_FIELD,words[wind--]));
|
||||
builder.add(new Term(DocMaker.BODY_FIELD, words[wind--]), i);
|
||||
if (remainedSlop>0) {
|
||||
remainedSlop--;
|
||||
wind--;
|
||||
}
|
||||
}
|
||||
builder.setSlop(slop + 2 * qlen);
|
||||
q = builder.build();
|
||||
queries.add(q);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ public class MultiPhraseQuery extends Query {
|
|||
private int slop = 0;
|
||||
|
||||
/** Sets the phrase slop for this query.
|
||||
* @see PhraseQuery#setSlop(int)
|
||||
* @see PhraseQuery#getSlop()
|
||||
*/
|
||||
public void setSlop(int s) {
|
||||
if (s < 0) {
|
||||
|
@ -70,14 +70,11 @@ public class MultiPhraseQuery extends Query {
|
|||
public int getSlop() { return slop; }
|
||||
|
||||
/** Add a single term at the next position in the phrase.
|
||||
* @see PhraseQuery#add(Term)
|
||||
*/
|
||||
public void add(Term term) { add(new Term[]{term}); }
|
||||
|
||||
/** Add multiple terms at the next position in the phrase. Any of the terms
|
||||
* may match.
|
||||
*
|
||||
* @see PhraseQuery#add(Term)
|
||||
*/
|
||||
public void add(Term[] terms) {
|
||||
int position = 0;
|
||||
|
@ -89,8 +86,6 @@ public class MultiPhraseQuery extends Query {
|
|||
|
||||
/**
|
||||
* Allows to specify the relative position of terms within the phrase.
|
||||
*
|
||||
* @see PhraseQuery#add(Term, int)
|
||||
*/
|
||||
public void add(Term[] terms, int position) {
|
||||
Objects.requireNonNull(terms, "Term array must not be null");
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.lucene.search;
|
|||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.Term;
|
||||
|
@ -30,70 +31,93 @@ import org.apache.lucene.index.Term;
|
|||
* will query "AB/0 BC/1 CD/2" (where term/position).
|
||||
*
|
||||
*/
|
||||
public class NGramPhraseQuery extends PhraseQuery {
|
||||
public class NGramPhraseQuery extends Query {
|
||||
|
||||
private final int n;
|
||||
private final PhraseQuery phraseQuery;
|
||||
|
||||
/**
|
||||
* Constructor that takes gram size.
|
||||
* @param n n-gram size
|
||||
*/
|
||||
public NGramPhraseQuery(int n){
|
||||
public NGramPhraseQuery(int n, PhraseQuery query) {
|
||||
super();
|
||||
this.n = n;
|
||||
this.phraseQuery = Objects.requireNonNull(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query rewrite(IndexReader reader) throws IOException {
|
||||
if(getSlop() != 0) return super.rewrite(reader);
|
||||
|
||||
// check whether optimizable or not
|
||||
if(n < 2 || // non-overlap n-gram cannot be optimized
|
||||
getTerms().length < 3) // too short to optimize
|
||||
return super.rewrite(reader);
|
||||
final Term[] terms = phraseQuery.getTerms();
|
||||
final int[] positions = phraseQuery.getPositions();
|
||||
|
||||
// check all posIncrement is 1
|
||||
// if not, cannot optimize
|
||||
int[] positions = getPositions();
|
||||
Term[] terms = getTerms();
|
||||
int prevPosition = positions[0];
|
||||
for(int i = 1; i < positions.length; i++){
|
||||
int pos = positions[i];
|
||||
if(prevPosition + 1 != pos) return super.rewrite(reader);
|
||||
prevPosition = pos;
|
||||
}
|
||||
boolean isOptimizable = phraseQuery.getSlop() == 0
|
||||
&& n >= 2 // non-overlap n-gram cannot be optimized
|
||||
&& terms.length >= 3; // short ones can't be optimized
|
||||
|
||||
// now create the new optimized phrase query for n-gram
|
||||
PhraseQuery optimized = new PhraseQuery();
|
||||
optimized.setBoost(getBoost());
|
||||
int pos = 0;
|
||||
final int lastPos = terms.length - 1;
|
||||
for(int i = 0; i < terms.length; i++){
|
||||
if(pos % n == 0 || pos >= lastPos){
|
||||
optimized.add(terms[i], positions[i]);
|
||||
if (isOptimizable) {
|
||||
for (int i = 1; i < positions.length; ++i) {
|
||||
if (positions[i] != positions[i-1] + 1) {
|
||||
isOptimizable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
return optimized;
|
||||
if (isOptimizable == false) {
|
||||
return phraseQuery.rewrite(reader);
|
||||
}
|
||||
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
for (int i = 0; i < terms.length; ++i) {
|
||||
if (i % n == 0 || i == terms.length - 1) {
|
||||
builder.add(terms[i], i);
|
||||
}
|
||||
}
|
||||
PhraseQuery rewritten = builder.build();
|
||||
rewritten.setBoost(phraseQuery.getBoost());
|
||||
return rewritten;
|
||||
}
|
||||
|
||||
/** Returns true iff <code>o</code> is equal to this. */
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof NGramPhraseQuery))
|
||||
if (super.equals(o) == false) {
|
||||
return false;
|
||||
NGramPhraseQuery other = (NGramPhraseQuery)o;
|
||||
if(this.n != other.n) return false;
|
||||
return super.equals(other);
|
||||
}
|
||||
NGramPhraseQuery other = (NGramPhraseQuery) o;
|
||||
return n == other.n && phraseQuery.equals(other.phraseQuery);
|
||||
}
|
||||
|
||||
/** Returns a hash code value for this object.*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Float.floatToIntBits(getBoost())
|
||||
^ getSlop()
|
||||
^ getTerms().hashCode()
|
||||
^ getPositions().hashCode()
|
||||
^ n;
|
||||
int h = super.hashCode();
|
||||
h = 31 * h + phraseQuery.hashCode();
|
||||
h = 31 * h + n;
|
||||
return h;
|
||||
}
|
||||
|
||||
/** Return the list of terms. */
|
||||
public Term[] getTerms() {
|
||||
return phraseQuery.getTerms();
|
||||
}
|
||||
|
||||
/** Return the list of relative positions that each term should appear at. */
|
||||
public int[] getPositions() {
|
||||
return phraseQuery.getPositions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBoost() {
|
||||
return phraseQuery.getBoost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoost(float b) {
|
||||
phraseQuery.setBoost(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return phraseQuery.toString(field);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,14 +20,15 @@ package org.apache.lucene.search;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.lucene.index.PostingsEnum;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.IndexReaderContext;
|
||||
import org.apache.lucene.index.LeafReader;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.PostingsEnum;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.index.TermContext;
|
||||
import org.apache.lucene.index.TermState;
|
||||
|
@ -37,6 +38,7 @@ import org.apache.lucene.search.similarities.Similarity;
|
|||
import org.apache.lucene.search.similarities.Similarity.SimScorer;
|
||||
import org.apache.lucene.util.ArrayUtil;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.ToStringUtils;
|
||||
|
||||
/** A Query that matches documents containing a particular sequence of terms.
|
||||
|
@ -47,127 +49,235 @@ import org.apache.lucene.util.ToStringUtils;
|
|||
* <b>NOTE</b>: Leading holes don't have any particular meaning for this query
|
||||
* and will be ignored. For instance this query:
|
||||
* <pre class="prettyprint">
|
||||
* PhraseQuery pq = new PhraseQuery();
|
||||
* pq.add(new Term("body", "one"), 4);
|
||||
* pq.add(new Term("body", "two"), 5);
|
||||
* PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
* builder.add(new Term("body", "one"), 4);
|
||||
* builder.add(new Term("body", "two"), 5);
|
||||
* PhraseQuery pq = builder.build();
|
||||
* </pre>
|
||||
* is equivalent to the below query:
|
||||
* <pre class="prettyprint">
|
||||
* PhraseQuery pq = new PhraseQuery();
|
||||
* pq.add(new Term("body", "one"), 0);
|
||||
* pq.add(new Term("body", "two"), 1);
|
||||
* PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
* builder.add(new Term("body", "one"), 0);
|
||||
* builder.add(new Term("body", "two"), 1);
|
||||
* PhraseQuery pq = builder.build();
|
||||
* </pre>
|
||||
*/
|
||||
public class PhraseQuery extends Query {
|
||||
private String field;
|
||||
private ArrayList<Term> terms = new ArrayList<>(4);
|
||||
private ArrayList<Integer> positions = new ArrayList<>(4);
|
||||
private int slop = 0;
|
||||
|
||||
/** Constructs an empty phrase query. */
|
||||
public PhraseQuery() {}
|
||||
/** A builder for phrase queries. */
|
||||
public static class Builder {
|
||||
|
||||
/** Sets the number of other words permitted between words in query phrase.
|
||||
If zero, then this is an exact phrase search. For larger values this works
|
||||
like a <code>WITHIN</code> or <code>NEAR</code> operator.
|
||||
private int slop;
|
||||
private final List<Term> terms;
|
||||
private final List<Integer> positions;
|
||||
|
||||
<p>The slop is in fact an edit-distance, where the units correspond to
|
||||
moves of terms in the query phrase out of position. For example, to switch
|
||||
the order of two words requires two moves (the first move places the words
|
||||
atop one another), so to permit re-orderings of phrases, the slop must be
|
||||
at least two.
|
||||
|
||||
<p>More exact matches are scored higher than sloppier matches, thus search
|
||||
results are sorted by exactness.
|
||||
|
||||
<p>The slop is zero by default, requiring exact matches.*/
|
||||
public void setSlop(int s) {
|
||||
if (s < 0) {
|
||||
throw new IllegalArgumentException("slop value cannot be negative");
|
||||
/** Sole constructor. */
|
||||
public Builder() {
|
||||
slop = 0;
|
||||
terms = new ArrayList<>();
|
||||
positions = new ArrayList<>();
|
||||
}
|
||||
slop = s;
|
||||
|
||||
/**
|
||||
* Set the slop.
|
||||
* @see PhraseQuery#getSlop()
|
||||
*/
|
||||
public void setSlop(int slop) {
|
||||
this.slop = slop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a term to the end of the query phrase.
|
||||
* The relative position of the term is the one immediately after the last term added.
|
||||
*/
|
||||
public void add(Term term) {
|
||||
add(term, positions.isEmpty() ? 0 : 1 + positions.get(positions.size() - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a term to the end of the query phrase.
|
||||
* The relative position of the term within the phrase is specified explicitly.
|
||||
* This allows e.g. phrases with more than one term at the same position
|
||||
* or phrases with gaps (e.g. in connection with stopwords).
|
||||
*
|
||||
*/
|
||||
public void add(Term term, int position) {
|
||||
term = new Term(term.field(), BytesRef.deepCopyOf(term.bytes())); // be defensive
|
||||
if (position < 0) {
|
||||
throw new IllegalArgumentException("Positions must be >= 0, got " + position);
|
||||
}
|
||||
if (positions.isEmpty() == false) {
|
||||
final int lastPosition = positions.get(positions.size() - 1);
|
||||
if (position < lastPosition) {
|
||||
throw new IllegalArgumentException("Positions must be added in order, got " + position + " after " + lastPosition);
|
||||
}
|
||||
}
|
||||
if (terms.isEmpty() == false && term.field().equals(terms.get(0).field()) == false) {
|
||||
throw new IllegalArgumentException("All terms must be on the same field, got " + term.field() + " and " + terms.get(0).field());
|
||||
}
|
||||
terms.add(term);
|
||||
positions.add(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a phrase query based on the terms that have been added.
|
||||
*/
|
||||
public PhraseQuery build() {
|
||||
Term[] terms = this.terms.toArray(new Term[this.terms.size()]);
|
||||
int[] positions = new int[this.positions.size()];
|
||||
for (int i = 0; i < positions.length; ++i) {
|
||||
positions[i] = this.positions.get(i);
|
||||
}
|
||||
return new PhraseQuery(slop, terms, positions);
|
||||
}
|
||||
|
||||
}
|
||||
/** Returns the slop. See setSlop(). */
|
||||
|
||||
private final int slop;
|
||||
private final String field;
|
||||
private final Term[] terms;
|
||||
private final int[] positions;
|
||||
|
||||
private PhraseQuery(int slop, Term[] terms, int[] positions) {
|
||||
if (terms.length != positions.length) {
|
||||
throw new IllegalArgumentException("Must have as many terms as positions");
|
||||
}
|
||||
if (slop < 0) {
|
||||
throw new IllegalArgumentException("Slop must be >= 0, got " + slop);
|
||||
}
|
||||
for (int i = 1; i < terms.length; ++i) {
|
||||
if (terms[i-1].field().equals(terms[i].field()) == false) {
|
||||
throw new IllegalArgumentException("All terms should have the same field");
|
||||
}
|
||||
}
|
||||
for (int position : positions) {
|
||||
if (position < 0) {
|
||||
throw new IllegalArgumentException("Positions must be >= 0, got " + position);
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < positions.length; ++i) {
|
||||
if (positions[i] < positions[i - 1]) {
|
||||
throw new IllegalArgumentException("Positions should not go backwards, got "
|
||||
+ positions[i-1] + " before " + positions[i]);
|
||||
}
|
||||
}
|
||||
this.slop = slop;
|
||||
this.terms = terms;
|
||||
this.positions = positions;
|
||||
this.field = terms.length == 0 ? null : terms[0].field();
|
||||
}
|
||||
|
||||
private static int[] incrementalPositions(int length) {
|
||||
int[] positions = new int[length];
|
||||
for (int i = 0; i < length; ++i) {
|
||||
positions[i] = i;
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
private static Term[] toTerms(String field, String... termStrings) {
|
||||
Term[] terms = new Term[termStrings.length];
|
||||
for (int i = 0; i < terms.length; ++i) {
|
||||
terms[i] = new Term(field, termStrings[i]);
|
||||
}
|
||||
return terms;
|
||||
}
|
||||
|
||||
private static Term[] toTerms(String field, BytesRef... termBytes) {
|
||||
Term[] terms = new Term[termBytes.length];
|
||||
for (int i = 0; i < terms.length; ++i) {
|
||||
terms[i] = new Term(field, BytesRef.deepCopyOf(termBytes[i]));
|
||||
}
|
||||
return terms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a phrase query which will match documents that contain the given
|
||||
* list of terms at consecutive positions in {@code field}, and at a
|
||||
* maximum edit distance of {@code slop}. For more complicated use-cases,
|
||||
* use {@link PhraseQuery.Builder}.
|
||||
* @see #getSlop()
|
||||
*/
|
||||
public PhraseQuery(int slop, String field, String... terms) {
|
||||
this(slop, toTerms(field, terms), incrementalPositions(terms.length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a phrase query which will match documents that contain the given
|
||||
* list of terms at consecutive positions in {@code field}.
|
||||
*/
|
||||
public PhraseQuery(String field, String... terms) {
|
||||
this(0, field, terms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a phrase query which will match documents that contain the given
|
||||
* list of terms at consecutive positions in {@code field}, and at a
|
||||
* maximum edit distance of {@code slop}. For more complicated use-cases,
|
||||
* use {@link PhraseQuery.Builder}.
|
||||
* @see #getSlop()
|
||||
*/
|
||||
public PhraseQuery(int slop, String field, BytesRef... terms) {
|
||||
this(slop, toTerms(field, terms), incrementalPositions(terms.length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a phrase query which will match documents that contain the given
|
||||
* list of terms at consecutive positions in {@code field}.
|
||||
*/
|
||||
public PhraseQuery(String field, BytesRef... terms) {
|
||||
this(0, field, terms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the slop for this {@link PhraseQuery}.
|
||||
*
|
||||
* <p>The slop is an edit distance between respective positions of terms as
|
||||
* defined in this {@link PhraseQuery} and the positions of terms in a
|
||||
* document.
|
||||
*
|
||||
* <p>For instance, when searching for {@code "quick fox"}, it is expected that
|
||||
* the difference between the positions of {@code fox} and {@code quick} is 1.
|
||||
* So {@code "a quick brown fox"} would be at an edit distance of 1 since the
|
||||
* difference of the positions of {@code fox} and {@code quick} is 2.
|
||||
* Similarly, {@code "the fox is quick"} would be at an edit distance of 3
|
||||
* since the difference of the positions of {@code fox} and {@code quick} is -2.
|
||||
* The slop defines the maximum edit distance for a document to match.
|
||||
*
|
||||
* <p>More exact matches are scored higher than sloppier matches, thus search
|
||||
* results are sorted by exactness.
|
||||
*/
|
||||
public int getSlop() { return slop; }
|
||||
|
||||
/**
|
||||
* Adds a term to the end of the query phrase.
|
||||
* The relative position of the term is the one immediately after the last term added.
|
||||
*/
|
||||
public void add(Term term) {
|
||||
int position = 0;
|
||||
if (positions.size() > 0) {
|
||||
position = positions.get(positions.size()-1) + 1;
|
||||
}
|
||||
|
||||
add(term, position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a term to the end of the query phrase.
|
||||
* The relative position of the term within the phrase is specified explicitly.
|
||||
* This allows e.g. phrases with more than one term at the same position
|
||||
* or phrases with gaps (e.g. in connection with stopwords).
|
||||
*
|
||||
*/
|
||||
public void add(Term term, int position) {
|
||||
Objects.requireNonNull(term, "Term must not be null");
|
||||
if (positions.size() > 0) {
|
||||
final int previousPosition = positions.get(positions.size()-1);
|
||||
if (position < previousPosition) {
|
||||
throw new IllegalArgumentException("Positions must be added in order. Got position="
|
||||
+ position + " while previous position was " + previousPosition);
|
||||
}
|
||||
} else if (position < 0) {
|
||||
throw new IllegalArgumentException("Positions must be positive, got " + position);
|
||||
}
|
||||
|
||||
if (terms.size() == 0) {
|
||||
field = term.field();
|
||||
} else if (!term.field().equals(field)) {
|
||||
throw new IllegalArgumentException("All phrase terms must be in the same field: " + term);
|
||||
}
|
||||
|
||||
terms.add(term);
|
||||
positions.add(Integer.valueOf(position));
|
||||
}
|
||||
|
||||
/** Returns the set of terms in this phrase. */
|
||||
/** Returns the list of terms in this phrase. */
|
||||
public Term[] getTerms() {
|
||||
return terms.toArray(new Term[0]);
|
||||
return terms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the relative positions of terms in this phrase.
|
||||
*/
|
||||
public int[] getPositions() {
|
||||
int[] result = new int[positions.size()];
|
||||
for(int i = 0; i < positions.size(); i++)
|
||||
result[i] = positions.get(i).intValue();
|
||||
return result;
|
||||
return positions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query rewrite(IndexReader reader) throws IOException {
|
||||
if (terms.isEmpty()) {
|
||||
if (terms.length == 0) {
|
||||
BooleanQuery bq = new BooleanQuery();
|
||||
bq.setBoost(getBoost());
|
||||
return bq;
|
||||
} else if (terms.size() == 1) {
|
||||
TermQuery tq = new TermQuery(terms.get(0));
|
||||
} else if (terms.length == 1) {
|
||||
TermQuery tq = new TermQuery(terms[0]);
|
||||
tq.setBoost(getBoost());
|
||||
return tq;
|
||||
} else if (positions.get(0).intValue() != 0) {
|
||||
// PhraseWeight requires that positions start at 0 so we need to rebase
|
||||
// positions
|
||||
final Term[] terms = getTerms();
|
||||
final int[] positions = getPositions();
|
||||
PhraseQuery rewritten = new PhraseQuery();
|
||||
for (int i = 0; i < terms.length; ++i) {
|
||||
rewritten.add(terms[i], positions[i] - positions[0]);
|
||||
} else if (positions[0] != 0) {
|
||||
int[] newPositions = new int[positions.length];
|
||||
for (int i = 0; i < positions.length; ++i) {
|
||||
newPositions[i] = positions[i] - positions[0];
|
||||
}
|
||||
PhraseQuery rewritten = new PhraseQuery(slop, terms, newPositions);
|
||||
rewritten.setBoost(getBoost());
|
||||
rewritten.setSlop(getSlop());
|
||||
return rewritten;
|
||||
} else {
|
||||
return super.rewrite(reader);
|
||||
|
@ -257,10 +367,10 @@ public class PhraseQuery extends Query {
|
|||
this.needsScores = needsScores;
|
||||
this.similarity = searcher.getSimilarity(needsScores);
|
||||
final IndexReaderContext context = searcher.getTopReaderContext();
|
||||
states = new TermContext[terms.size()];
|
||||
TermStatistics termStats[] = new TermStatistics[terms.size()];
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
final Term term = terms.get(i);
|
||||
states = new TermContext[terms.length];
|
||||
TermStatistics termStats[] = new TermStatistics[terms.length];
|
||||
for (int i = 0; i < terms.length; i++) {
|
||||
final Term term = terms[i];
|
||||
states[i] = TermContext.build(context, term);
|
||||
termStats[i] = searcher.termStatistics(term, states[i]);
|
||||
}
|
||||
|
@ -269,7 +379,7 @@ public class PhraseQuery extends Query {
|
|||
|
||||
@Override
|
||||
public void extractTerms(Set<Term> queryTerms) {
|
||||
queryTerms.addAll(terms);
|
||||
Collections.addAll(queryTerms, terms);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -287,10 +397,10 @@ public class PhraseQuery extends Query {
|
|||
|
||||
@Override
|
||||
public Scorer scorer(LeafReaderContext context, Bits acceptDocs) throws IOException {
|
||||
assert !terms.isEmpty();
|
||||
assert terms.length > 0;
|
||||
final LeafReader reader = context.reader();
|
||||
final Bits liveDocs = acceptDocs;
|
||||
PostingsAndFreq[] postingsFreqs = new PostingsAndFreq[terms.size()];
|
||||
PostingsAndFreq[] postingsFreqs = new PostingsAndFreq[terms.length];
|
||||
|
||||
final Terms fieldTerms = reader.terms(field);
|
||||
if (fieldTerms == null) {
|
||||
|
@ -304,8 +414,8 @@ public class PhraseQuery extends Query {
|
|||
// Reuse single TermsEnum below:
|
||||
final TermsEnum te = fieldTerms.iterator();
|
||||
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
final Term t = terms.get(i);
|
||||
for (int i = 0; i < terms.length; i++) {
|
||||
final Term t = terms[i];
|
||||
final TermState state = states[i].get(context.ord);
|
||||
if (state == null) { /* term doesnt exist in this segment */
|
||||
assert termNotInReader(reader, t): "no termstate found but term exists in reader";
|
||||
|
@ -313,7 +423,7 @@ public class PhraseQuery extends Query {
|
|||
}
|
||||
te.seekExact(t.bytes(), state);
|
||||
PostingsEnum postingsEnum = te.postings(liveDocs, null, PostingsEnum.POSITIONS);
|
||||
postingsFreqs[i] = new PostingsAndFreq(postingsEnum, positions.get(i), t);
|
||||
postingsFreqs[i] = new PostingsAndFreq(postingsEnum, positions[i], t);
|
||||
}
|
||||
|
||||
// sort by increasing docFreq order
|
||||
|
@ -370,19 +480,19 @@ public class PhraseQuery extends Query {
|
|||
|
||||
buffer.append("\"");
|
||||
final int maxPosition;
|
||||
if (positions.isEmpty()) {
|
||||
if (positions.length == 0) {
|
||||
maxPosition = -1;
|
||||
} else {
|
||||
maxPosition = positions.get(positions.size() - 1);
|
||||
maxPosition = positions[positions.length - 1];
|
||||
}
|
||||
String[] pieces = new String[maxPosition + 1];
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
int pos = positions.get(i).intValue();
|
||||
for (int i = 0; i < terms.length; i++) {
|
||||
int pos = positions[i];
|
||||
String s = pieces[pos];
|
||||
if (s == null) {
|
||||
s = (terms.get(i)).text();
|
||||
s = (terms[i]).text();
|
||||
} else {
|
||||
s = s + "|" + (terms.get(i)).text();
|
||||
s = s + "|" + (terms[i]).text();
|
||||
}
|
||||
pieces[pos] = s;
|
||||
}
|
||||
|
@ -412,22 +522,23 @@ public class PhraseQuery extends Query {
|
|||
/** Returns true iff <code>o</code> is equal to this. */
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof PhraseQuery))
|
||||
if (super.equals(o) == false) {
|
||||
return false;
|
||||
PhraseQuery other = (PhraseQuery)o;
|
||||
return super.equals(o)
|
||||
&& (this.slop == other.slop)
|
||||
&& this.terms.equals(other.terms)
|
||||
&& this.positions.equals(other.positions);
|
||||
}
|
||||
PhraseQuery that = (PhraseQuery) o;
|
||||
return slop == that.slop
|
||||
&& Arrays.equals(terms, that.terms)
|
||||
&& Arrays.equals(positions, that.positions);
|
||||
}
|
||||
|
||||
/** Returns a hash code value for this object.*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode()
|
||||
^ slop
|
||||
^ terms.hashCode()
|
||||
^ positions.hashCode();
|
||||
int h = super.hashCode();
|
||||
h = 31 * h + slop;
|
||||
h = 31 * h + Arrays.hashCode(terms);
|
||||
h = 31 * h + Arrays.hashCode(positions);
|
||||
return h;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -664,7 +664,7 @@ public abstract class TFIDFSimilarity extends Similarity {
|
|||
* return larger values when the edit distance is small and smaller values
|
||||
* when it is large.
|
||||
*
|
||||
* @see PhraseQuery#setSlop(int)
|
||||
* @see PhraseQuery#getSlop()
|
||||
* @param distance the edit distance of this sloppy phrase match
|
||||
* @return the frequency increment for this match
|
||||
*/
|
||||
|
|
|
@ -329,8 +329,8 @@ public class QueryBuilder {
|
|||
* Creates simple phrase query from the cached tokenstream contents
|
||||
*/
|
||||
private Query analyzePhrase(String field, TokenStream stream, int slop) throws IOException {
|
||||
PhraseQuery pq = newPhraseQuery();
|
||||
pq.setSlop(slop);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.setSlop(slop);
|
||||
|
||||
TermToBytesRefAttribute termAtt = stream.getAttribute(TermToBytesRefAttribute.class);
|
||||
BytesRef bytes = termAtt.getBytesRef();
|
||||
|
@ -344,13 +344,13 @@ public class QueryBuilder {
|
|||
|
||||
if (enablePositionIncrements) {
|
||||
position += posIncrAtt.getPositionIncrement();
|
||||
pq.add(new Term(field, BytesRef.deepCopyOf(bytes)), position);
|
||||
} else {
|
||||
pq.add(new Term(field, BytesRef.deepCopyOf(bytes)));
|
||||
position += 1;
|
||||
}
|
||||
builder.add(new Term(field, bytes), position);
|
||||
}
|
||||
|
||||
return pq;
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -414,16 +414,6 @@ public class QueryBuilder {
|
|||
return new TermQuery(term);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new PhraseQuery instance.
|
||||
* <p>
|
||||
* This is intended for subclasses that wish to customize the generated queries.
|
||||
* @return new PhraseQuery instance
|
||||
*/
|
||||
protected PhraseQuery newPhraseQuery() {
|
||||
return new PhraseQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new MultiPhraseQuery instance.
|
||||
* <p>
|
||||
|
|
|
@ -70,9 +70,7 @@ public class TestDemo extends LuceneTestCase {
|
|||
}
|
||||
|
||||
// Test simple phrase query
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term("fieldname", "to"));
|
||||
phraseQuery.add(new Term("fieldname", "be"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery("fieldname", "to", "be");
|
||||
assertEquals(1, isearcher.search(phraseQuery, 1).totalHits);
|
||||
|
||||
ireader.close();
|
||||
|
|
|
@ -167,15 +167,10 @@ public class TestSearch extends LuceneTestCase {
|
|||
booleanAB.add(new TermQuery(new Term("contents", "b")), BooleanClause.Occur.SHOULD);
|
||||
queries.add(booleanAB);
|
||||
|
||||
PhraseQuery phraseAB = new PhraseQuery();
|
||||
phraseAB.add(new Term("contents", "a"));
|
||||
phraseAB.add(new Term("contents", "b"));
|
||||
PhraseQuery phraseAB = new PhraseQuery("contents", "a", "b");
|
||||
queries.add(phraseAB);
|
||||
|
||||
PhraseQuery phraseABC = new PhraseQuery();
|
||||
phraseABC.add(new Term("contents", "a"));
|
||||
phraseABC.add(new Term("contents", "b"));
|
||||
phraseABC.add(new Term("contents", "c"));
|
||||
PhraseQuery phraseABC = new PhraseQuery("contents", "a", "b", "c");
|
||||
queries.add(phraseABC);
|
||||
|
||||
BooleanQuery booleanAC = new BooleanQuery();
|
||||
|
@ -183,15 +178,10 @@ public class TestSearch extends LuceneTestCase {
|
|||
booleanAC.add(new TermQuery(new Term("contents", "c")), BooleanClause.Occur.SHOULD);
|
||||
queries.add(booleanAC);
|
||||
|
||||
PhraseQuery phraseAC = new PhraseQuery();
|
||||
phraseAC.add(new Term("contents", "a"));
|
||||
phraseAC.add(new Term("contents", "c"));
|
||||
PhraseQuery phraseAC = new PhraseQuery("contents", "a", "c");
|
||||
queries.add(phraseAC);
|
||||
|
||||
PhraseQuery phraseACE = new PhraseQuery();
|
||||
phraseACE.add(new Term("contents", "a"));
|
||||
phraseACE.add(new Term("contents", "c"));
|
||||
phraseACE.add(new Term("contents", "e"));
|
||||
PhraseQuery phraseACE = new PhraseQuery("contents", "a", "c", "e");
|
||||
queries.add(phraseACE);
|
||||
|
||||
return queries;
|
||||
|
|
|
@ -246,9 +246,7 @@ public class TestDocument extends LuceneTestCase {
|
|||
IndexReader reader = writer.getReader();
|
||||
|
||||
IndexSearcher searcher = newSearcher(reader);
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term("indexed_not_tokenized", "test1"));
|
||||
query.add(new Term("indexed_not_tokenized", "test2"));
|
||||
PhraseQuery query = new PhraseQuery("indexed_not_tokenized", "test1", "test2");
|
||||
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals(1, hits.length);
|
||||
|
|
|
@ -172,9 +172,7 @@ public class TestAddIndexes extends LuceneTestCase {
|
|||
writer.updateDocument(new Term("id", "" + (i%10)), doc);
|
||||
}
|
||||
// Deletes one of the 10 added docs, leaving 9:
|
||||
PhraseQuery q = new PhraseQuery();
|
||||
q.add(new Term("content", "bbb"));
|
||||
q.add(new Term("content", "14"));
|
||||
PhraseQuery q = new PhraseQuery("content", "bbb", "14");
|
||||
writer.deleteDocuments(q);
|
||||
|
||||
writer.forceMerge(1);
|
||||
|
@ -210,9 +208,7 @@ public class TestAddIndexes extends LuceneTestCase {
|
|||
writer.addIndexes(aux);
|
||||
|
||||
// Deletes one of the 10 added docs, leaving 9:
|
||||
PhraseQuery q = new PhraseQuery();
|
||||
q.add(new Term("content", "bbb"));
|
||||
q.add(new Term("content", "14"));
|
||||
PhraseQuery q = new PhraseQuery("content", "bbb", "14");
|
||||
writer.deleteDocuments(q);
|
||||
|
||||
writer.forceMerge(1);
|
||||
|
@ -246,9 +242,7 @@ public class TestAddIndexes extends LuceneTestCase {
|
|||
}
|
||||
|
||||
// Deletes one of the 10 added docs, leaving 9:
|
||||
PhraseQuery q = new PhraseQuery();
|
||||
q.add(new Term("content", "bbb"));
|
||||
q.add(new Term("content", "14"));
|
||||
PhraseQuery q = new PhraseQuery("content", "bbb", "14");
|
||||
writer.deleteDocuments(q);
|
||||
|
||||
writer.addIndexes(aux);
|
||||
|
|
|
@ -1894,9 +1894,10 @@ public class TestIndexWriter extends LuceneTestCase {
|
|||
IndexReader ir = iw.getReader();
|
||||
iw.close();
|
||||
IndexSearcher is = newSearcher(ir);
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("body", "just"), 0);
|
||||
pq.add(new Term("body", "test"), 2);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("body", "just"), 0);
|
||||
builder.add(new Term("body", "test"), 2);
|
||||
PhraseQuery pq = builder.build();
|
||||
// body:"just ? test"
|
||||
assertEquals(1, is.search(pq, 5).totalHits);
|
||||
ir.close();
|
||||
|
@ -1925,9 +1926,10 @@ public class TestIndexWriter extends LuceneTestCase {
|
|||
IndexReader ir = iw.getReader();
|
||||
iw.close();
|
||||
IndexSearcher is = newSearcher(ir);
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("body", "just"), 0);
|
||||
pq.add(new Term("body", "test"), 3);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("body", "just"), 0);
|
||||
builder.add(new Term("body", "test"), 3);
|
||||
PhraseQuery pq = builder.build();
|
||||
// body:"just ? ? test"
|
||||
assertEquals(1, is.search(pq, 5).totalHits);
|
||||
ir.close();
|
||||
|
|
|
@ -1410,14 +1410,10 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
|
|||
w.close();
|
||||
|
||||
final IndexSearcher s = newSearcher(r);
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("content", "silly"));
|
||||
pq.add(new Term("content", "content"));
|
||||
PhraseQuery pq = new PhraseQuery("content", "silly", "good");
|
||||
assertEquals(0, s.search(pq, 1).totalHits);
|
||||
|
||||
pq = new PhraseQuery();
|
||||
pq.add(new Term("content", "good"));
|
||||
pq.add(new Term("content", "content"));
|
||||
pq = new PhraseQuery("content", "good", "content");
|
||||
assertEquals(numDocs1+numDocs2, s.search(pq, 1).totalHits);
|
||||
r.close();
|
||||
dir.close();
|
||||
|
@ -1491,14 +1487,10 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
|
|||
w.close();
|
||||
|
||||
final IndexSearcher s = newSearcher(r);
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("content", "silly"));
|
||||
pq.add(new Term("content", "content"));
|
||||
PhraseQuery pq = new PhraseQuery("content", "silly", "content");
|
||||
assertEquals(numDocs2, s.search(pq, 1).totalHits);
|
||||
|
||||
pq = new PhraseQuery();
|
||||
pq.add(new Term("content", "good"));
|
||||
pq.add(new Term("content", "content"));
|
||||
pq = new PhraseQuery("content", "good", "content");
|
||||
assertEquals(numDocs1+numDocs3+numDocs4, s.search(pq, 1).totalHits);
|
||||
r.close();
|
||||
dir.close();
|
||||
|
|
|
@ -111,9 +111,7 @@ public class TestLazyProxSkipping extends LuceneTestCase {
|
|||
|
||||
private ScoreDoc[] search() throws IOException {
|
||||
// create PhraseQuery "term1 term2" and search
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term(this.field, this.term1));
|
||||
pq.add(new Term(this.field, this.term2));
|
||||
PhraseQuery pq = new PhraseQuery(field, term1, term2);
|
||||
return this.searcher.search(pq, 1000).scoreDocs;
|
||||
}
|
||||
|
||||
|
|
|
@ -308,9 +308,7 @@ public class TestOmitTf extends LuceneTestCase {
|
|||
TermQuery q3 = new TermQuery(c);
|
||||
TermQuery q4 = new TermQuery(d);
|
||||
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(a);
|
||||
pq.add(c);
|
||||
PhraseQuery pq = new PhraseQuery(a.field(), a.bytes(), c.bytes());
|
||||
try {
|
||||
searcher.search(pq, 10);
|
||||
fail("did not hit expected exception");
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.lucene.search.similarities.DefaultSimilarity;
|
|||
import org.apache.lucene.search.similarities.Similarity;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.MockDirectoryWrapper;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.apache.lucene.util.TestUtil;
|
||||
import org.junit.AfterClass;
|
||||
|
@ -332,13 +333,9 @@ public class TestBoolean2 extends LuceneTestCase {
|
|||
if (qType < 3) {
|
||||
q = new TermQuery(new Term(field, vals[rnd.nextInt(vals.length)]));
|
||||
} else if (qType < 4) {
|
||||
Term t1 = new Term(field, vals[rnd.nextInt(vals.length)]);
|
||||
Term t2 = new Term(field, vals[rnd.nextInt(vals.length)]);
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(t1);
|
||||
pq.add(t2);
|
||||
pq.setSlop(10); // increase possibility of matching
|
||||
q = pq;
|
||||
String t1 = vals[rnd.nextInt(vals.length)];
|
||||
String t2 = vals[rnd.nextInt(vals.length)];
|
||||
q = new PhraseQuery(10, field, t1, t2); // slop increases possibility of matching
|
||||
} else if (qType < 7) {
|
||||
q = new WildcardQuery(new Term(field, "w*"));
|
||||
} else {
|
||||
|
|
|
@ -110,9 +110,7 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
|
||||
// LUCENE-2617: make sure that a clause not in the index still contributes to the score via coord factor
|
||||
BooleanQuery qq = q.clone();
|
||||
PhraseQuery phrase = new PhraseQuery();
|
||||
phrase.add(new Term("field", "not_in_index"));
|
||||
phrase.add(new Term("field", "another_not_in_index"));
|
||||
PhraseQuery phrase = new PhraseQuery("field", "not_in_index", "another_not_in_index");
|
||||
phrase.setBoost(0);
|
||||
qq.add(phrase, BooleanClause.Occur.SHOULD);
|
||||
score2 = s.search(qq, 10).getMaxScore();
|
||||
|
@ -126,14 +124,14 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
assertEquals(score*(2/3F), score2, 1e-6);
|
||||
|
||||
// PhraseQuery w/ no terms added returns a null scorer
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
PhraseQuery pq = new PhraseQuery("field", new String[0]);
|
||||
q.add(pq, BooleanClause.Occur.SHOULD);
|
||||
assertEquals(1, s.search(q, 10).totalHits);
|
||||
|
||||
// A required clause which returns null scorer should return null scorer to
|
||||
// IndexSearcher.
|
||||
q = new BooleanQuery();
|
||||
pq = new PhraseQuery();
|
||||
pq = new PhraseQuery("field", new String[0]);
|
||||
q.add(new TermQuery(new Term("field", "a")), BooleanClause.Occur.SHOULD);
|
||||
q.add(pq, BooleanClause.Occur.MUST);
|
||||
assertEquals(0, s.search(q, 10).totalHits);
|
||||
|
@ -610,9 +608,7 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
final IndexSearcher searcher = new IndexSearcher(reader);
|
||||
searcher.setQueryCache(null); // to still have approximations
|
||||
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("field", "a"));
|
||||
pq.add(new Term("field", "b"));
|
||||
PhraseQuery pq = new PhraseQuery("field", "a", "b");
|
||||
|
||||
BooleanQuery q = new BooleanQuery();
|
||||
q.add(pq, Occur.MUST);
|
||||
|
@ -641,9 +637,7 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
final IndexSearcher searcher = new IndexSearcher(reader);
|
||||
searcher.setQueryCache(null); // to still have approximations
|
||||
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("field", "a"));
|
||||
pq.add(new Term("field", "b"));
|
||||
PhraseQuery pq = new PhraseQuery("field", "a", "b");
|
||||
|
||||
BooleanQuery q = new BooleanQuery();
|
||||
q.add(pq, Occur.SHOULD);
|
||||
|
@ -674,9 +668,7 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
final IndexSearcher searcher = new IndexSearcher(reader);
|
||||
searcher.setQueryCache(null); // to still have approximations
|
||||
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("field", "a"));
|
||||
pq.add(new Term("field", "b"));
|
||||
PhraseQuery pq = new PhraseQuery("field", "a", "b");
|
||||
|
||||
BooleanQuery q = new BooleanQuery();
|
||||
q.add(pq, Occur.SHOULD);
|
||||
|
@ -705,9 +697,7 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
final IndexSearcher searcher = new IndexSearcher(reader);
|
||||
searcher.setQueryCache(null); // to still have approximations
|
||||
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("field", "a"));
|
||||
pq.add(new Term("field", "b"));
|
||||
PhraseQuery pq = new PhraseQuery("field", "a", "b");
|
||||
|
||||
BooleanQuery q = new BooleanQuery();
|
||||
q.add(pq, Occur.SHOULD);
|
||||
|
@ -736,9 +726,7 @@ public class TestBooleanQuery extends LuceneTestCase {
|
|||
final IndexSearcher searcher = new IndexSearcher(reader);
|
||||
searcher.setQueryCache(null); // to still have approximations
|
||||
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("field", "a"));
|
||||
pq.add(new Term("field", "b"));
|
||||
PhraseQuery pq = new PhraseQuery("field", "a", "b");
|
||||
|
||||
BooleanQuery q = new BooleanQuery();
|
||||
q.add(pq, Occur.MUST);
|
||||
|
|
|
@ -60,10 +60,7 @@ public class TestComplexExplanations extends BaseExplanationTestCase {
|
|||
|
||||
BooleanQuery q = new BooleanQuery();
|
||||
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.setSlop(1);
|
||||
phraseQuery.add(new Term(FIELD, "w1"));
|
||||
phraseQuery.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(1, FIELD, "w1", "w2");
|
||||
q.add(phraseQuery, Occur.MUST);
|
||||
q.add(snear(st("w2"),
|
||||
sor("w5","zz"),
|
||||
|
@ -123,10 +120,7 @@ public class TestComplexExplanations extends BaseExplanationTestCase {
|
|||
|
||||
BooleanQuery q = new BooleanQuery();
|
||||
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.setSlop(1);
|
||||
phraseQuery.add(new Term(FIELD, "w1"));
|
||||
phraseQuery.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(1, FIELD, "w1", "w2");
|
||||
q.add(phraseQuery, Occur.MUST);
|
||||
q.add(snear(st("w2"),
|
||||
sor("w5","zz"),
|
||||
|
|
|
@ -231,9 +231,7 @@ public class TestConstantScoreQuery extends LuceneTestCase {
|
|||
final IndexSearcher searcher = newSearcher(reader);
|
||||
searcher.setQueryCache(null); // to still have approximations
|
||||
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("field", "a"));
|
||||
pq.add(new Term("field", "b"));
|
||||
PhraseQuery pq = new PhraseQuery("field", "a", "b");
|
||||
|
||||
ConstantScoreQuery q = new ConstantScoreQuery(pq);
|
||||
|
||||
|
|
|
@ -850,10 +850,9 @@ public class TestLRUQueryCache extends LuceneTestCase {
|
|||
bq.setMinimumNumberShouldMatch(TestUtil.nextInt(random(), 0, numShould));
|
||||
return bq;
|
||||
case 2:
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(randomTerm());
|
||||
pq.add(randomTerm());
|
||||
pq.setSlop(random().nextInt(2));
|
||||
Term t1 = randomTerm();
|
||||
Term t2 = randomTerm();
|
||||
PhraseQuery pq = new PhraseQuery(random().nextInt(2), t1.field(), t1.bytes(), t2.bytes());
|
||||
return pq;
|
||||
case 3:
|
||||
return new MatchAllDocsQuery();
|
||||
|
|
|
@ -496,17 +496,18 @@ public class TestMultiPhraseQuery extends LuceneTestCase {
|
|||
* PQ AND Mode - Manually creating a phrase query
|
||||
*/
|
||||
public void testZeroPosIncrSloppyPqAnd() throws IOException {
|
||||
final PhraseQuery pq = new PhraseQuery();
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
int pos = -1;
|
||||
for (Token tap : INCR_0_QUERY_TOKENS_AND) {
|
||||
pos += tap.getPositionIncrement();
|
||||
pq.add(new Term("field",tap.toString()), pos);
|
||||
builder.add(new Term("field", tap.toString()), pos);
|
||||
}
|
||||
doTestZeroPosIncrSloppy(pq, 0);
|
||||
pq.setSlop(1);
|
||||
doTestZeroPosIncrSloppy(pq, 0);
|
||||
pq.setSlop(2);
|
||||
doTestZeroPosIncrSloppy(pq, 1);
|
||||
builder.setSlop(0);
|
||||
doTestZeroPosIncrSloppy(builder.build(), 0);
|
||||
builder.setSlop(1);
|
||||
doTestZeroPosIncrSloppy(builder.build(), 0);
|
||||
builder.setSlop(2);
|
||||
doTestZeroPosIncrSloppy(builder.build(), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -49,51 +49,36 @@ public class TestNGramPhraseQuery extends LuceneTestCase {
|
|||
|
||||
public void testRewrite() throws Exception {
|
||||
// bi-gram test ABC => AB/BC => AB/BC
|
||||
PhraseQuery pq1 = new NGramPhraseQuery(2);
|
||||
pq1.add(new Term("f", "AB"));
|
||||
pq1.add(new Term("f", "BC"));
|
||||
NGramPhraseQuery pq1 = new NGramPhraseQuery(2, new PhraseQuery("f", "AB", "BC"));
|
||||
|
||||
Query q = pq1.rewrite(reader);
|
||||
assertTrue(q instanceof NGramPhraseQuery);
|
||||
assertSame(pq1, q);
|
||||
pq1 = (NGramPhraseQuery)q;
|
||||
assertArrayEquals(new Term[]{new Term("f", "AB"), new Term("f", "BC")}, pq1.getTerms());
|
||||
assertArrayEquals(new int[]{0, 1}, pq1.getPositions());
|
||||
assertSame(q.rewrite(reader), q);
|
||||
PhraseQuery rewritten1 = (PhraseQuery) q;
|
||||
assertArrayEquals(new Term[]{new Term("f", "AB"), new Term("f", "BC")}, rewritten1.getTerms());
|
||||
assertArrayEquals(new int[]{0, 1}, rewritten1.getPositions());
|
||||
|
||||
// bi-gram test ABCD => AB/BC/CD => AB//CD
|
||||
PhraseQuery pq2 = new NGramPhraseQuery(2);
|
||||
pq2.add(new Term("f", "AB"));
|
||||
pq2.add(new Term("f", "BC"));
|
||||
pq2.add(new Term("f", "CD"));
|
||||
NGramPhraseQuery pq2 = new NGramPhraseQuery(2, new PhraseQuery("f", "AB", "BC", "CD"));
|
||||
|
||||
q = pq2.rewrite(reader);
|
||||
assertTrue(q instanceof PhraseQuery);
|
||||
assertNotSame(pq2, q);
|
||||
pq2 = (PhraseQuery)q;
|
||||
assertArrayEquals(new Term[]{new Term("f", "AB"), new Term("f", "CD")}, pq2.getTerms());
|
||||
assertArrayEquals(new int[]{0, 2}, pq2.getPositions());
|
||||
PhraseQuery rewritten2 = (PhraseQuery) q;
|
||||
assertArrayEquals(new Term[]{new Term("f", "AB"), new Term("f", "CD")}, rewritten2.getTerms());
|
||||
assertArrayEquals(new int[]{0, 2}, rewritten2.getPositions());
|
||||
|
||||
// tri-gram test ABCDEFGH => ABC/BCD/CDE/DEF/EFG/FGH => ABC///DEF//FGH
|
||||
PhraseQuery pq3 = new NGramPhraseQuery(3);
|
||||
pq3.add(new Term("f", "ABC"));
|
||||
pq3.add(new Term("f", "BCD"));
|
||||
pq3.add(new Term("f", "CDE"));
|
||||
pq3.add(new Term("f", "DEF"));
|
||||
pq3.add(new Term("f", "EFG"));
|
||||
pq3.add(new Term("f", "FGH"));
|
||||
NGramPhraseQuery pq3 = new NGramPhraseQuery(3, new PhraseQuery("f", "ABC", "BCD", "CDE", "DEF", "EFG", "FGH"));
|
||||
|
||||
q = pq3.rewrite(reader);
|
||||
assertTrue(q instanceof PhraseQuery);
|
||||
assertNotSame(pq3, q);
|
||||
pq3 = (PhraseQuery)q;
|
||||
assertArrayEquals(new Term[]{new Term("f", "ABC"), new Term("f", "DEF"), new Term("f", "FGH")}, pq3.getTerms());
|
||||
assertArrayEquals(new int[]{0, 3, 5}, pq3.getPositions());
|
||||
PhraseQuery rewritten3 = (PhraseQuery) q;
|
||||
assertArrayEquals(new Term[]{new Term("f", "ABC"), new Term("f", "DEF"), new Term("f", "FGH")}, rewritten3.getTerms());
|
||||
assertArrayEquals(new int[]{0, 3, 5}, rewritten3.getPositions());
|
||||
|
||||
// LUCENE-4970: boosting test
|
||||
PhraseQuery pq4 = new NGramPhraseQuery(2);
|
||||
pq4.add(new Term("f", "AB"));
|
||||
pq4.add(new Term("f", "BC"));
|
||||
pq4.add(new Term("f", "CD"));
|
||||
NGramPhraseQuery pq4 = new NGramPhraseQuery(2, new PhraseQuery("f", "AB", "BC", "CD"));
|
||||
pq4.setBoost(100.0F);
|
||||
|
||||
q = pq4.rewrite(reader);
|
||||
|
|
|
@ -97,7 +97,6 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
query = new PhraseQuery();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
@ -110,18 +109,14 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testNotCloseEnough() throws Exception {
|
||||
query.setSlop(2);
|
||||
query.add(new Term("field", "one"));
|
||||
query.add(new Term("field", "five"));
|
||||
query = new PhraseQuery(2, "field", "one", "five");
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals(0, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
}
|
||||
|
||||
public void testBarelyCloseEnough() throws Exception {
|
||||
query.setSlop(3);
|
||||
query.add(new Term("field", "one"));
|
||||
query.add(new Term("field", "five"));
|
||||
query = new PhraseQuery(3, "field", "one", "five");
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals(1, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
@ -132,16 +127,13 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
*/
|
||||
public void testExact() throws Exception {
|
||||
// slop is zero by default
|
||||
query.add(new Term("field", "four"));
|
||||
query.add(new Term("field", "five"));
|
||||
query = new PhraseQuery("field", "four", "five");
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("exact match", 1, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
||||
|
||||
query = new PhraseQuery();
|
||||
query.add(new Term("field", "two"));
|
||||
query.add(new Term("field", "one"));
|
||||
query = new PhraseQuery("field", "two", "one");
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("reverse not exact", 0, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
@ -149,9 +141,7 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
|
||||
public void testSlop1() throws Exception {
|
||||
// Ensures slop of 1 works with terms in order.
|
||||
query.setSlop(1);
|
||||
query.add(new Term("field", "one"));
|
||||
query.add(new Term("field", "two"));
|
||||
query = new PhraseQuery(1, "field", "one", "two");
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("in order", 1, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
@ -159,10 +149,7 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
|
||||
// Ensures slop of 1 does not work for phrases out of order;
|
||||
// must be at least 2.
|
||||
query = new PhraseQuery();
|
||||
query.setSlop(1);
|
||||
query.add(new Term("field", "two"));
|
||||
query.add(new Term("field", "one"));
|
||||
query = new PhraseQuery(1, "field", "two", "one");
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("reversed, slop not 2 or more", 0, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
@ -172,18 +159,14 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
* As long as slop is at least 2, terms can be reversed
|
||||
*/
|
||||
public void testOrderDoesntMatter() throws Exception {
|
||||
query.setSlop(2); // must be at least two for reverse order match
|
||||
query.add(new Term("field", "two"));
|
||||
query.add(new Term("field", "one"));
|
||||
// must be at least two for reverse order match
|
||||
query = new PhraseQuery(2, "field", "two", "one");
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("just sloppy enough", 1, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
||||
|
||||
query = new PhraseQuery();
|
||||
query.setSlop(2);
|
||||
query.add(new Term("field", "three"));
|
||||
query.add(new Term("field", "one"));
|
||||
query = new PhraseQuery(2, "field", "three", "one");
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("not sloppy enough", 0, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
@ -195,26 +178,19 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
* to line up a phrase
|
||||
*/
|
||||
public void testMultipleTerms() throws Exception {
|
||||
query.setSlop(2);
|
||||
query.add(new Term("field", "one"));
|
||||
query.add(new Term("field", "three"));
|
||||
query.add(new Term("field", "five"));
|
||||
query = new PhraseQuery(2, "field", "one", "three", "five");
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("two total moves", 1, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
||||
|
||||
query = new PhraseQuery();
|
||||
query.setSlop(5); // it takes six moves to match this phrase
|
||||
query.add(new Term("field", "five"));
|
||||
query.add(new Term("field", "three"));
|
||||
query.add(new Term("field", "one"));
|
||||
// it takes six moves to match this phrase
|
||||
query = new PhraseQuery(5, "field", "five", "three", "one");
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("slop of 5 not close enough", 0, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
||||
|
||||
query.setSlop(6);
|
||||
query = new PhraseQuery(6, "field", "five", "three", "one");
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("slop of 6 just right", 1, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
@ -235,9 +211,7 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
IndexSearcher searcher = newSearcher(reader);
|
||||
|
||||
// valid exact phrase query
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term("field","stop"));
|
||||
query.add(new Term("field","words"));
|
||||
PhraseQuery query = new PhraseQuery("field", "stop", "words");
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals(1, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
@ -264,9 +238,7 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
|
||||
IndexSearcher searcher = newSearcher(reader);
|
||||
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term("source", "marketing"));
|
||||
phraseQuery.add(new Term("source", "info"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery("source", "marketing", "info");
|
||||
ScoreDoc[] hits = searcher.search(phraseQuery, 1000).scoreDocs;
|
||||
assertEquals(2, hits.length);
|
||||
QueryUtils.check(random(), phraseQuery,searcher);
|
||||
|
@ -303,9 +275,7 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
searcher = newSearcher(reader);
|
||||
|
||||
termQuery = new TermQuery(new Term("contents","woo"));
|
||||
phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term("contents","map"));
|
||||
phraseQuery.add(new Term("contents","entry"));
|
||||
phraseQuery = new PhraseQuery("contents", "map", "entry");
|
||||
|
||||
hits = searcher.search(termQuery, 1000).scoreDocs;
|
||||
assertEquals(3, hits.length);
|
||||
|
@ -355,10 +325,7 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
|
||||
IndexSearcher searcher = newSearcher(reader);
|
||||
searcher.setSimilarity(new DefaultSimilarity());
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term("field", "firstname"));
|
||||
query.add(new Term("field", "lastname"));
|
||||
query.setSlop(Integer.MAX_VALUE);
|
||||
PhraseQuery query = new PhraseQuery(Integer.MAX_VALUE, "field", "firstname", "lastname");
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals(3, hits.length);
|
||||
// Make sure that those matches where the terms appear closer to
|
||||
|
@ -375,25 +342,35 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testToString() throws Exception {
|
||||
PhraseQuery q = new PhraseQuery();
|
||||
PhraseQuery q = new PhraseQuery("field", new String[0]);
|
||||
assertEquals("\"\"", q.toString());
|
||||
|
||||
q.add(new Term("field", "hi"), 1);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("field", "hi"), 1);
|
||||
q = builder.build();
|
||||
assertEquals("field:\"? hi\"", q.toString());
|
||||
|
||||
q = new PhraseQuery(); // Query "this hi this is a test is"
|
||||
q.add(new Term("field", "hi"), 1);
|
||||
q.add(new Term("field", "test"), 5);
|
||||
|
||||
builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("field", "hi"), 1);
|
||||
builder.add(new Term("field", "test"), 5);
|
||||
q = builder.build(); // Query "this hi this is a test is"
|
||||
|
||||
assertEquals("field:\"? hi ? ? ? test\"", q.toString());
|
||||
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "hi"), 1);
|
||||
q.add(new Term("field", "hello"), 1);
|
||||
q.add(new Term("field", "test"), 5);
|
||||
builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("field", "hi"), 1);
|
||||
builder.add(new Term("field", "hello"), 1);
|
||||
builder.add(new Term("field", "test"), 5);
|
||||
q = builder.build();
|
||||
assertEquals("field:\"? hi|hello ? ? ? test\"", q.toString());
|
||||
|
||||
q.setSlop(5);
|
||||
builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("field", "hi"), 1);
|
||||
builder.add(new Term("field", "hello"), 1);
|
||||
builder.add(new Term("field", "test"), 5);
|
||||
builder.setSlop(5);
|
||||
q = builder.build();
|
||||
assertEquals("field:\"? hi|hello ? ? ? test\"~5", q.toString());
|
||||
|
||||
q.setBoost(2);
|
||||
|
@ -401,17 +378,13 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testWrappedPhrase() throws IOException {
|
||||
query.add(new Term("repeated", "first"));
|
||||
query.add(new Term("repeated", "part"));
|
||||
query.add(new Term("repeated", "second"));
|
||||
query.add(new Term("repeated", "part"));
|
||||
query.setSlop(100);
|
||||
query = new PhraseQuery(100, "repeated", "first", "part", "second", "part");
|
||||
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("slop of 100 just right", 1, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
||||
query.setSlop(99);
|
||||
query = new PhraseQuery(99, "repeated", "first", "part", "second", "part");
|
||||
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("slop of 99 not enough", 0, hits.length);
|
||||
|
@ -421,44 +394,28 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
// work on two docs like this: "phrase exist notexist exist found"
|
||||
public void testNonExistingPhrase() throws IOException {
|
||||
// phrase without repetitions that exists in 2 docs
|
||||
query.add(new Term("nonexist", "phrase"));
|
||||
query.add(new Term("nonexist", "notexist"));
|
||||
query.add(new Term("nonexist", "found"));
|
||||
query.setSlop(2); // would be found this way
|
||||
query = new PhraseQuery(2, "nonexist", "phrase", "notexist", "found");
|
||||
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("phrase without repetitions exists in 2 docs", 2, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
||||
// phrase with repetitions that exists in 2 docs
|
||||
query = new PhraseQuery();
|
||||
query.add(new Term("nonexist", "phrase"));
|
||||
query.add(new Term("nonexist", "exist"));
|
||||
query.add(new Term("nonexist", "exist"));
|
||||
query.setSlop(1); // would be found
|
||||
query = new PhraseQuery(1, "nonexist", "phrase", "exist", "exist");
|
||||
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("phrase with repetitions exists in two docs", 2, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
||||
// phrase I with repetitions that does not exist in any doc
|
||||
query = new PhraseQuery();
|
||||
query.add(new Term("nonexist", "phrase"));
|
||||
query.add(new Term("nonexist", "notexist"));
|
||||
query.add(new Term("nonexist", "phrase"));
|
||||
query.setSlop(1000); // would not be found no matter how high the slop is
|
||||
query = new PhraseQuery(1000, "nonexist", "phrase", "notexist", "phrase");
|
||||
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("nonexisting phrase with repetitions does not exist in any doc", 0, hits.length);
|
||||
QueryUtils.check(random(), query,searcher);
|
||||
|
||||
// phrase II with repetitions that does not exist in any doc
|
||||
query = new PhraseQuery();
|
||||
query.add(new Term("nonexist", "phrase"));
|
||||
query.add(new Term("nonexist", "exist"));
|
||||
query.add(new Term("nonexist", "exist"));
|
||||
query.add(new Term("nonexist", "exist"));
|
||||
query.setSlop(1000); // would not be found no matter how high the slop is
|
||||
query = new PhraseQuery(1000, "nonexist", "phrase", "exist", "exist", "exist");
|
||||
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("nonexisting phrase with repetitions does not exist in any doc", 0, hits.length);
|
||||
|
@ -478,9 +435,7 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
public void testPalyndrome2() throws Exception {
|
||||
|
||||
// search on non palyndrome, find phrase with no slop, using exact phrase scorer
|
||||
query.setSlop(0); // to use exact phrase scorer
|
||||
query.add(new Term("field", "two"));
|
||||
query.add(new Term("field", "three"));
|
||||
query = new PhraseQuery("field", "two", "three"); // to use exact phrase scorer
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("phrase found with exact phrase scorer", 1, hits.length);
|
||||
float score0 = hits[0].score;
|
||||
|
@ -488,7 +443,7 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
QueryUtils.check(random(), query,searcher);
|
||||
|
||||
// search on non palyndrome, find phrase with slop 2, though no slop required here.
|
||||
query.setSlop(2); // to use sloppy scorer
|
||||
query = new PhraseQuery("field", "two", "three"); // to use sloppy scorer
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("just sloppy enough", 1, hits.length);
|
||||
float score1 = hits[0].score;
|
||||
|
@ -497,10 +452,7 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
QueryUtils.check(random(), query,searcher);
|
||||
|
||||
// search ordered in palyndrome, find it twice
|
||||
query = new PhraseQuery();
|
||||
query.setSlop(2); // must be at least two for both ordered and reversed to match
|
||||
query.add(new Term("palindrome", "two"));
|
||||
query.add(new Term("palindrome", "three"));
|
||||
query = new PhraseQuery(2, "palindrome", "two", "three"); // must be at least two for both ordered and reversed to match
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("just sloppy enough", 1, hits.length);
|
||||
//float score2 = hits[0].score;
|
||||
|
@ -511,10 +463,7 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
//assertTrue("ordered scores higher in palindrome",score1+SCORE_COMP_THRESH<score2);
|
||||
|
||||
// search reveresed in palyndrome, find it twice
|
||||
query = new PhraseQuery();
|
||||
query.setSlop(2); // must be at least two for both ordered and reversed to match
|
||||
query.add(new Term("palindrome", "three"));
|
||||
query.add(new Term("palindrome", "two"));
|
||||
query = new PhraseQuery(2, "palindrome", "three", "two"); // must be at least two for both ordered and reversed to match
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("just sloppy enough", 1, hits.length);
|
||||
//float score3 = hits[0].score;
|
||||
|
@ -538,10 +487,8 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
public void testPalyndrome3() throws Exception {
|
||||
|
||||
// search on non palyndrome, find phrase with no slop, using exact phrase scorer
|
||||
query.setSlop(0); // to use exact phrase scorer
|
||||
query.add(new Term("field", "one"));
|
||||
query.add(new Term("field", "two"));
|
||||
query.add(new Term("field", "three"));
|
||||
// slop=0 to use exact phrase scorer
|
||||
query = new PhraseQuery(0, "field", "one", "two", "three");
|
||||
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("phrase found with exact phrase scorer", 1, hits.length);
|
||||
float score0 = hits[0].score;
|
||||
|
@ -552,7 +499,8 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
searcher.explain(query, 0);
|
||||
|
||||
// search on non palyndrome, find phrase with slop 3, though no slop required here.
|
||||
query.setSlop(4); // to use sloppy scorer
|
||||
// slop=4 to use sloppy scorer
|
||||
query = new PhraseQuery(4, "field", "one", "two", "three");
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("just sloppy enough", 1, hits.length);
|
||||
float score1 = hits[0].score;
|
||||
|
@ -561,11 +509,8 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
QueryUtils.check(random(), query,searcher);
|
||||
|
||||
// search ordered in palyndrome, find it twice
|
||||
query = new PhraseQuery();
|
||||
query.setSlop(4); // must be at least four for both ordered and reversed to match
|
||||
query.add(new Term("palindrome", "one"));
|
||||
query.add(new Term("palindrome", "two"));
|
||||
query.add(new Term("palindrome", "three"));
|
||||
// slop must be at least four for both ordered and reversed to match
|
||||
query = new PhraseQuery(4, "palindrome", "one", "two", "three");
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
|
||||
// just make sure no exc:
|
||||
|
@ -580,11 +525,8 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
//assertTrue("ordered scores higher in palindrome",score1+SCORE_COMP_THRESH<score2);
|
||||
|
||||
// search reveresed in palyndrome, find it twice
|
||||
query = new PhraseQuery();
|
||||
query.setSlop(4); // must be at least four for both ordered and reversed to match
|
||||
query.add(new Term("palindrome", "three"));
|
||||
query.add(new Term("palindrome", "two"));
|
||||
query.add(new Term("palindrome", "one"));
|
||||
// must be at least four for both ordered and reversed to match
|
||||
query = new PhraseQuery(4, "palindrome", "three", "two", "one");
|
||||
hits = searcher.search(query, 1000).scoreDocs;
|
||||
assertEquals("just sloppy enough", 1, hits.length);
|
||||
//float score3 = hits[0].score;
|
||||
|
@ -599,14 +541,13 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
// LUCENE-1280
|
||||
public void testEmptyPhraseQuery() throws Throwable {
|
||||
final BooleanQuery q2 = new BooleanQuery();
|
||||
q2.add(new PhraseQuery(), BooleanClause.Occur.MUST);
|
||||
q2.add(new PhraseQuery("field", new String[0]), BooleanClause.Occur.MUST);
|
||||
q2.toString();
|
||||
}
|
||||
|
||||
/* test that a single term is rewritten to a term query */
|
||||
public void testRewrite() throws IOException {
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("foo", "bar"));
|
||||
PhraseQuery pq = new PhraseQuery("foo", "bar");
|
||||
Query rewritten = pq.rewrite(searcher.getIndexReader());
|
||||
assertTrue(rewritten instanceof TermQuery);
|
||||
}
|
||||
|
@ -680,12 +621,13 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
|
||||
final int numTerm = TestUtil.nextInt(r, 2, 20);
|
||||
final int start = r.nextInt(doc.size()-numTerm);
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int t=start;t<start+numTerm;t++) {
|
||||
pq.add(new Term("f", doc.get(t)));
|
||||
builder.add(new Term("f", doc.get(t)), t);
|
||||
sb.append(doc.get(t)).append(' ');
|
||||
}
|
||||
PhraseQuery pq = builder.build();
|
||||
|
||||
TopDocs hits = s.search(pq, NUM_DOCS);
|
||||
boolean found = false;
|
||||
|
@ -704,11 +646,8 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testNegativeSlop() throws Exception {
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term("field", "two"));
|
||||
query.add(new Term("field", "one"));
|
||||
try {
|
||||
query.setSlop(-2);
|
||||
new PhraseQuery(-2, "field", "two", "one");
|
||||
fail("didn't get expected exception");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
// expected exception
|
||||
|
@ -716,9 +655,9 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testNegativePosition() throws Exception {
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
try {
|
||||
query.add(new Term("field", "two"), -42);
|
||||
builder.add(new Term("field", "two"), -42);
|
||||
fail("didn't get expected exception");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
// expected exception
|
||||
|
@ -726,11 +665,11 @@ public class TestPhraseQuery extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testBackwardPositions() throws Exception {
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term("field", "one"), 1);
|
||||
query.add(new Term("field", "two"), 5);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("field", "one"), 1);
|
||||
builder.add(new Term("field", "two"), 5);
|
||||
try {
|
||||
query.add(new Term("field", "three"), 4);
|
||||
builder.add(new Term("field", "three"), 4);
|
||||
fail("didn't get expected exception");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
// expected exception
|
||||
|
|
|
@ -123,50 +123,56 @@ public class TestPositionIncrement extends LuceneTestCase {
|
|||
PhraseQuery q;
|
||||
ScoreDoc[] hits;
|
||||
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "1"));
|
||||
q.add(new Term("field", "2"));
|
||||
q = new PhraseQuery("field", "1", "2");
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(0, hits.length);
|
||||
|
||||
// same as previous, using the builder with implicit positions
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("field", "1"));
|
||||
builder.add(new Term("field", "2"));
|
||||
q = builder.build();
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(0, hits.length);
|
||||
|
||||
// same as previous, just specify positions explicitely.
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "1"),0);
|
||||
q.add(new Term("field", "2"),1);
|
||||
builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("field", "1"), 0);
|
||||
builder.add(new Term("field", "2"), 1);
|
||||
q = builder.build();
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(0, hits.length);
|
||||
|
||||
// specifying correct positions should find the phrase.
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "1"),0);
|
||||
q.add(new Term("field", "2"),2);
|
||||
builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("field", "1"), 0);
|
||||
builder.add(new Term("field", "2"), 2);
|
||||
q = builder.build();
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(1, hits.length);
|
||||
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "2"));
|
||||
q.add(new Term("field", "3"));
|
||||
q = new PhraseQuery("field", "2", "3");
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(1, hits.length);
|
||||
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "3"));
|
||||
q.add(new Term("field", "4"));
|
||||
q = new PhraseQuery("field", "3", "4");
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(0, hits.length);
|
||||
|
||||
// phrase query would find it when correct positions are specified.
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "3"),0);
|
||||
q.add(new Term("field", "4"),0);
|
||||
builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("field", "3"), 0);
|
||||
builder.add(new Term("field", "4"), 0);
|
||||
q = builder.build();
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(1, hits.length);
|
||||
|
||||
// phrase query should fail for non existing searched term
|
||||
// even if there exist another searched terms in the same searched position.
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "3"),0);
|
||||
q.add(new Term("field", "9"),0);
|
||||
builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("field", "3"), 0);
|
||||
builder.add(new Term("field", "9"), 0);
|
||||
q = builder.build();
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(0, hits.length);
|
||||
|
||||
|
@ -177,27 +183,19 @@ public class TestPositionIncrement extends LuceneTestCase {
|
|||
hits = searcher.search(mq, 1000).scoreDocs;
|
||||
assertEquals(1, hits.length);
|
||||
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "2"));
|
||||
q.add(new Term("field", "4"));
|
||||
q = new PhraseQuery("field", "2", "4");
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(1, hits.length);
|
||||
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "3"));
|
||||
q.add(new Term("field", "5"));
|
||||
q = new PhraseQuery("field", "3", "5");
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(1, hits.length);
|
||||
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "4"));
|
||||
q.add(new Term("field", "5"));
|
||||
q = new PhraseQuery("field", "4", "5");
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(1, hits.length);
|
||||
|
||||
q = new PhraseQuery();
|
||||
q.add(new Term("field", "2"));
|
||||
q.add(new Term("field", "5"));
|
||||
q = new PhraseQuery("field", "2", "5");
|
||||
hits = searcher.search(q, 1000).scoreDocs;
|
||||
assertEquals(0, hits.length);
|
||||
|
||||
|
|
|
@ -79,10 +79,7 @@ public class TestQueryRescorer extends LuceneTestCase {
|
|||
assertEquals("1", searcher.doc(hits.scoreDocs[1].doc).get("id"));
|
||||
|
||||
// Now, resort using PhraseQuery:
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.setSlop(5);
|
||||
pq.add(new Term("field", "wizard"));
|
||||
pq.add(new Term("field", "oz"));
|
||||
PhraseQuery pq = new PhraseQuery(5, "field", "wizard", "oz");
|
||||
|
||||
TopDocs hits2 = QueryRescorer.rescore(searcher, hits, pq, 2.0, 10);
|
||||
|
||||
|
@ -176,10 +173,7 @@ public class TestQueryRescorer extends LuceneTestCase {
|
|||
|
||||
// Now, resort using PhraseQuery, but with an
|
||||
// opposite-world combine:
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.setSlop(5);
|
||||
pq.add(new Term("field", "wizard"));
|
||||
pq.add(new Term("field", "oz"));
|
||||
PhraseQuery pq = new PhraseQuery(5, "field", "wizard", "oz");
|
||||
|
||||
TopDocs hits2 = new QueryRescorer(pq) {
|
||||
@Override
|
||||
|
@ -229,9 +223,7 @@ public class TestQueryRescorer extends LuceneTestCase {
|
|||
assertEquals("1", searcher.doc(hits.scoreDocs[1].doc).get("id"));
|
||||
|
||||
// Now, resort using PhraseQuery:
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("field", "wizard"));
|
||||
pq.add(new Term("field", "oz"));
|
||||
PhraseQuery pq = new PhraseQuery("field", "wizard", "oz");
|
||||
|
||||
Rescorer rescorer = new QueryRescorer(pq) {
|
||||
@Override
|
||||
|
@ -306,9 +298,7 @@ public class TestQueryRescorer extends LuceneTestCase {
|
|||
assertEquals("1", searcher.doc(hits.scoreDocs[1].doc).get("id"));
|
||||
|
||||
// Now, resort using PhraseQuery, no slop:
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("field", "wizard"));
|
||||
pq.add(new Term("field", "oz"));
|
||||
PhraseQuery pq = new PhraseQuery("field", "wizard", "oz");
|
||||
|
||||
TopDocs hits2 = QueryRescorer.rescore(searcher, hits, pq, 2.0, 10);
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ import org.apache.lucene.index.IndexWriterConfig.OpenMode;
|
|||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.BitDocIdSet;
|
||||
import org.apache.lucene.util.Bits;
|
||||
import org.apache.lucene.util.FixedBitSet;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
|
||||
|
@ -324,12 +324,14 @@ public class TestScorerPerf extends LuceneTestCase {
|
|||
|
||||
for (int i=0; i<iter; i++) {
|
||||
int nClauses = random().nextInt(maxClauses-1)+2; // min 2 clauses
|
||||
PhraseQuery q = new PhraseQuery();
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
for (int j=0; j<nClauses; j++) {
|
||||
int tnum = random().nextInt(termsInIndex);
|
||||
q.add(new Term("f",Character.toString((char)(tnum+'A'))), j);
|
||||
builder.add(new Term("f", Character.toString((char)(tnum+'A'))));
|
||||
}
|
||||
q.setSlop(termsInIndex); // this could be random too
|
||||
// slop could be random too
|
||||
builder.setSlop(termsInIndex);
|
||||
PhraseQuery q = builder.build();
|
||||
|
||||
CountingHitCollector hc = new CountingHitCollector();
|
||||
s.search(q, hc);
|
||||
|
|
|
@ -118,9 +118,7 @@ public class TestSimilarity extends LuceneTestCase {
|
|||
}
|
||||
});
|
||||
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(a);
|
||||
pq.add(c);
|
||||
PhraseQuery pq = new PhraseQuery(a.field(), a.bytes(), c.bytes());
|
||||
//System.out.println(pq.toString("field"));
|
||||
searcher.search(pq,
|
||||
new SimpleCollector() {
|
||||
|
@ -140,7 +138,7 @@ public class TestSimilarity extends LuceneTestCase {
|
|||
}
|
||||
});
|
||||
|
||||
pq.setSlop(2);
|
||||
pq = new PhraseQuery(2, a.field(), a.bytes(), c.bytes());
|
||||
//System.out.println(pq.toString("field"));
|
||||
searcher.search(pq, new SimpleCollector() {
|
||||
private Scorer scorer;
|
||||
|
|
|
@ -54,50 +54,31 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
/* some simple phrase tests */
|
||||
|
||||
public void testP1() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD, "w1"));
|
||||
phraseQuery.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(FIELD, "w1", "w2");
|
||||
qtest(phraseQuery, new int[] { 0 });
|
||||
}
|
||||
public void testP2() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD, "w1"));
|
||||
phraseQuery.add(new Term(FIELD, "w3"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(FIELD, "w1", "w3");
|
||||
qtest(phraseQuery, new int[] { 1,3 });
|
||||
}
|
||||
public void testP3() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.setSlop(1);
|
||||
phraseQuery.add(new Term(FIELD, "w1"));
|
||||
phraseQuery.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(1, FIELD, "w1", "w2");
|
||||
qtest(phraseQuery, new int[] { 0,1,2 });
|
||||
}
|
||||
public void testP4() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.setSlop(1);
|
||||
phraseQuery.add(new Term(FIELD, "w2"));
|
||||
phraseQuery.add(new Term(FIELD, "w3"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(1, FIELD, "w2", "w3");
|
||||
qtest(phraseQuery, new int[] { 0,1,2,3 });
|
||||
}
|
||||
public void testP5() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.setSlop(1);
|
||||
phraseQuery.add(new Term(FIELD, "w3"));
|
||||
phraseQuery.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(1, FIELD, "w3", "w2");
|
||||
qtest(phraseQuery, new int[] { 1,3 });
|
||||
}
|
||||
public void testP6() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.setSlop(2);
|
||||
phraseQuery.add(new Term(FIELD, "w3"));
|
||||
phraseQuery.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(2, FIELD, "w3", "w2");
|
||||
qtest(phraseQuery, new int[] { 0,1,3 });
|
||||
}
|
||||
public void testP7() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.setSlop(3);
|
||||
phraseQuery.add(new Term(FIELD, "w3"));
|
||||
phraseQuery.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(3, FIELD, "w3", "w2");
|
||||
qtest(phraseQuery, new int[] { 0,1,2,3 });
|
||||
}
|
||||
|
||||
|
@ -657,14 +638,10 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
public void testMultiFieldBQofPQ1() throws Exception {
|
||||
BooleanQuery query = new BooleanQuery();
|
||||
|
||||
PhraseQuery leftChild = new PhraseQuery();
|
||||
leftChild.add(new Term(FIELD, "w1"));
|
||||
leftChild.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery leftChild = new PhraseQuery(FIELD, "w1", "w2");
|
||||
query.add(leftChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
PhraseQuery rightChild = new PhraseQuery();
|
||||
rightChild.add(new Term(ALTFIELD, "w1"));
|
||||
rightChild.add(new Term(ALTFIELD, "w2"));
|
||||
PhraseQuery rightChild = new PhraseQuery(ALTFIELD, "w1", "w2");
|
||||
query.add(rightChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
qtest(query, new int[] { 0 });
|
||||
|
@ -672,14 +649,10 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
public void testMultiFieldBQofPQ2() throws Exception {
|
||||
BooleanQuery query = new BooleanQuery();
|
||||
|
||||
PhraseQuery leftChild = new PhraseQuery();
|
||||
leftChild.add(new Term(FIELD, "w1"));
|
||||
leftChild.add(new Term(FIELD, "w3"));
|
||||
PhraseQuery leftChild = new PhraseQuery(FIELD, "w1", "w3");
|
||||
query.add(leftChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
PhraseQuery rightChild = new PhraseQuery();
|
||||
rightChild.add(new Term(ALTFIELD, "w1"));
|
||||
rightChild.add(new Term(ALTFIELD, "w3"));
|
||||
PhraseQuery rightChild = new PhraseQuery(ALTFIELD, "w1", "w3");
|
||||
query.add(rightChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
qtest(query, new int[] { 1,3 });
|
||||
|
@ -687,16 +660,10 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
public void testMultiFieldBQofPQ3() throws Exception {
|
||||
BooleanQuery query = new BooleanQuery();
|
||||
|
||||
PhraseQuery leftChild = new PhraseQuery();
|
||||
leftChild.setSlop(1);
|
||||
leftChild.add(new Term(FIELD, "w1"));
|
||||
leftChild.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery leftChild = new PhraseQuery(1, FIELD, "w1", "w2");
|
||||
query.add(leftChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
PhraseQuery rightChild = new PhraseQuery();
|
||||
rightChild.setSlop(1);
|
||||
rightChild.add(new Term(ALTFIELD, "w1"));
|
||||
rightChild.add(new Term(ALTFIELD, "w2"));
|
||||
PhraseQuery rightChild = new PhraseQuery(1, ALTFIELD, "w1", "w2");
|
||||
query.add(rightChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
qtest(query, new int[] { 0,1,2 });
|
||||
|
@ -704,16 +671,10 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
public void testMultiFieldBQofPQ4() throws Exception {
|
||||
BooleanQuery query = new BooleanQuery();
|
||||
|
||||
PhraseQuery leftChild = new PhraseQuery();
|
||||
leftChild.setSlop(1);
|
||||
leftChild.add(new Term(FIELD, "w2"));
|
||||
leftChild.add(new Term(FIELD, "w3"));
|
||||
PhraseQuery leftChild = new PhraseQuery(1, FIELD, "w2", "w3");
|
||||
query.add(leftChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
PhraseQuery rightChild = new PhraseQuery();
|
||||
rightChild.setSlop(1);
|
||||
rightChild.add(new Term(ALTFIELD, "w2"));
|
||||
rightChild.add(new Term(ALTFIELD, "w3"));
|
||||
PhraseQuery rightChild = new PhraseQuery(1, ALTFIELD, "w2", "w3");
|
||||
query.add(rightChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
qtest(query, new int[] { 0,1,2,3 });
|
||||
|
@ -721,16 +682,10 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
public void testMultiFieldBQofPQ5() throws Exception {
|
||||
BooleanQuery query = new BooleanQuery();
|
||||
|
||||
PhraseQuery leftChild = new PhraseQuery();
|
||||
leftChild.setSlop(1);
|
||||
leftChild.add(new Term(FIELD, "w3"));
|
||||
leftChild.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery leftChild = new PhraseQuery(1, FIELD, "w3", "w2");
|
||||
query.add(leftChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
PhraseQuery rightChild = new PhraseQuery();
|
||||
rightChild.setSlop(1);
|
||||
rightChild.add(new Term(ALTFIELD, "w3"));
|
||||
rightChild.add(new Term(ALTFIELD, "w2"));
|
||||
PhraseQuery rightChild = new PhraseQuery(1, ALTFIELD, "w3", "w2");
|
||||
query.add(rightChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
qtest(query, new int[] { 1,3 });
|
||||
|
@ -738,16 +693,10 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
public void testMultiFieldBQofPQ6() throws Exception {
|
||||
BooleanQuery query = new BooleanQuery();
|
||||
|
||||
PhraseQuery leftChild = new PhraseQuery();
|
||||
leftChild.setSlop(2);
|
||||
leftChild.add(new Term(FIELD, "w3"));
|
||||
leftChild.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery leftChild = new PhraseQuery(2, FIELD, "w3", "w2");
|
||||
query.add(leftChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
PhraseQuery rightChild = new PhraseQuery();
|
||||
rightChild.setSlop(2);
|
||||
rightChild.add(new Term(ALTFIELD, "w3"));
|
||||
rightChild.add(new Term(ALTFIELD, "w2"));
|
||||
PhraseQuery rightChild = new PhraseQuery(2, ALTFIELD, "w3", "w2");
|
||||
query.add(rightChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
qtest(query, new int[] { 0,1,3 });
|
||||
|
@ -755,16 +704,10 @@ public class TestSimpleExplanations extends BaseExplanationTestCase {
|
|||
public void testMultiFieldBQofPQ7() throws Exception {
|
||||
BooleanQuery query = new BooleanQuery();
|
||||
|
||||
PhraseQuery leftChild = new PhraseQuery();
|
||||
leftChild.setSlop(3);
|
||||
leftChild.add(new Term(FIELD, "w3"));
|
||||
leftChild.add(new Term(FIELD, "w2"));
|
||||
PhraseQuery leftChild = new PhraseQuery(3, FIELD, "w3", "w2");
|
||||
query.add(leftChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
PhraseQuery rightChild = new PhraseQuery();
|
||||
rightChild.setSlop(1);
|
||||
rightChild.add(new Term(ALTFIELD, "w3"));
|
||||
rightChild.add(new Term(ALTFIELD, "w2"));
|
||||
PhraseQuery rightChild = new PhraseQuery(1, ALTFIELD, "w3", "w2");
|
||||
query.add(rightChild, BooleanClause.Occur.SHOULD);
|
||||
|
||||
qtest(query, new int[] { 0,1,2,3 });
|
||||
|
|
|
@ -92,9 +92,7 @@ public class TestSimpleSearchEquivalence extends SearchEquivalenceTestBase {
|
|||
public void testExactPhraseVersusBooleanAnd() throws Exception {
|
||||
Term t1 = randomTerm();
|
||||
Term t2 = randomTerm();
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2);
|
||||
PhraseQuery q1 = new PhraseQuery(t1.field(), t1.bytes(), t2.bytes());
|
||||
BooleanQuery q2 = new BooleanQuery();
|
||||
q2.add(new TermQuery(t1), Occur.MUST);
|
||||
q2.add(new TermQuery(t2), Occur.MUST);
|
||||
|
@ -105,9 +103,10 @@ public class TestSimpleSearchEquivalence extends SearchEquivalenceTestBase {
|
|||
public void testExactPhraseVersusBooleanAndWithHoles() throws Exception {
|
||||
Term t1 = randomTerm();
|
||||
Term t2 = randomTerm();
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2, 2);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(t1, 0);
|
||||
builder.add(t2, 2);
|
||||
PhraseQuery q1 = builder.build();
|
||||
BooleanQuery q2 = new BooleanQuery();
|
||||
q2.add(new TermQuery(t1), Occur.MUST);
|
||||
q2.add(new TermQuery(t2), Occur.MUST);
|
||||
|
@ -118,13 +117,8 @@ public class TestSimpleSearchEquivalence extends SearchEquivalenceTestBase {
|
|||
public void testPhraseVersusSloppyPhrase() throws Exception {
|
||||
Term t1 = randomTerm();
|
||||
Term t2 = randomTerm();
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t1);
|
||||
q2.add(t2);
|
||||
q2.setSlop(1);
|
||||
PhraseQuery q1 = new PhraseQuery(t1.field(), t1.bytes(), t2.bytes());
|
||||
PhraseQuery q2 = new PhraseQuery(1, t1.field(), t1.bytes(), t2.bytes());
|
||||
assertSubsetOf(q1, q2);
|
||||
}
|
||||
|
||||
|
@ -132,13 +126,12 @@ public class TestSimpleSearchEquivalence extends SearchEquivalenceTestBase {
|
|||
public void testPhraseVersusSloppyPhraseWithHoles() throws Exception {
|
||||
Term t1 = randomTerm();
|
||||
Term t2 = randomTerm();
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2, 2);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t1);
|
||||
q2.add(t2, 2);
|
||||
q2.setSlop(1);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(t1, 0);
|
||||
builder.add(t2, 2);
|
||||
PhraseQuery q1 = builder.build();
|
||||
builder.setSlop(2);
|
||||
PhraseQuery q2 = builder.build();
|
||||
assertSubsetOf(q1, q2);
|
||||
}
|
||||
|
||||
|
@ -146,9 +139,7 @@ public class TestSimpleSearchEquivalence extends SearchEquivalenceTestBase {
|
|||
public void testExactPhraseVersusMultiPhrase() throws Exception {
|
||||
Term t1 = randomTerm();
|
||||
Term t2 = randomTerm();
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2);
|
||||
PhraseQuery q1 = new PhraseQuery(t1.field(), t1.bytes(), t2.bytes());
|
||||
Term t3 = randomTerm();
|
||||
MultiPhraseQuery q2 = new MultiPhraseQuery();
|
||||
q2.add(t1);
|
||||
|
@ -160,9 +151,10 @@ public class TestSimpleSearchEquivalence extends SearchEquivalenceTestBase {
|
|||
public void testExactPhraseVersusMultiPhraseWithHoles() throws Exception {
|
||||
Term t1 = randomTerm();
|
||||
Term t2 = randomTerm();
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2, 2);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(t1, 0);
|
||||
builder.add(t2, 2);
|
||||
PhraseQuery q1 = builder.build();
|
||||
Term t3 = randomTerm();
|
||||
MultiPhraseQuery q2 = new MultiPhraseQuery();
|
||||
q2.add(t1);
|
||||
|
@ -179,10 +171,7 @@ public class TestSimpleSearchEquivalence extends SearchEquivalenceTestBase {
|
|||
do {
|
||||
t2 = randomTerm();
|
||||
} while (t1.equals(t2));
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2);
|
||||
q1.setSlop(Integer.MAX_VALUE);
|
||||
PhraseQuery q1 = new PhraseQuery(Integer.MAX_VALUE, t1.field(), t1.bytes(), t2.bytes());
|
||||
BooleanQuery q2 = new BooleanQuery();
|
||||
q2.add(new TermQuery(t1), Occur.MUST);
|
||||
q2.add(new TermQuery(t2), Occur.MUST);
|
||||
|
@ -193,12 +182,11 @@ public class TestSimpleSearchEquivalence extends SearchEquivalenceTestBase {
|
|||
public void testPhraseRelativePositions() throws Exception {
|
||||
Term t1 = randomTerm();
|
||||
Term t2 = randomTerm();
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t1, 10000);
|
||||
q2.add(t2, 10001);
|
||||
PhraseQuery q1 = new PhraseQuery(t1.field(), t1.bytes(), t2.bytes());
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(t1, 10000);
|
||||
builder.add(t2, 10001);
|
||||
PhraseQuery q2 = builder.build();
|
||||
assertSameScores(q1, q2);
|
||||
}
|
||||
|
||||
|
@ -206,14 +194,12 @@ public class TestSimpleSearchEquivalence extends SearchEquivalenceTestBase {
|
|||
public void testSloppyPhraseRelativePositions() throws Exception {
|
||||
Term t1 = randomTerm();
|
||||
Term t2 = randomTerm();
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2);
|
||||
q1.setSlop(2);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t1, 10000);
|
||||
q2.add(t2, 10001);
|
||||
q2.setSlop(2);
|
||||
PhraseQuery q1 = new PhraseQuery(2, t1.field(), t1.bytes(), t2.bytes());
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(t1, 10000);
|
||||
builder.add(t2, 10001);
|
||||
builder.setSlop(2);
|
||||
PhraseQuery q2 = builder.build();
|
||||
assertSameScores(q1, q2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ package org.apache.lucene.search;
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.lucene.analysis.MockAnalyzer;
|
||||
import org.apache.lucene.analysis.MockTokenizer;
|
||||
import org.apache.lucene.document.Document;
|
||||
|
@ -31,8 +33,6 @@ import org.apache.lucene.store.MockDirectoryWrapper;
|
|||
import org.apache.lucene.store.RAMDirectory;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TestSloppyPhraseQuery extends LuceneTestCase {
|
||||
|
||||
private static final String S_1 = "A A A";
|
||||
|
@ -135,7 +135,14 @@ public class TestSloppyPhraseQuery extends LuceneTestCase {
|
|||
}
|
||||
|
||||
private float checkPhraseQuery(Document doc, PhraseQuery query, int slop, int expectedNumResults) throws Exception {
|
||||
query.setSlop(slop);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
Term[] terms = query.getTerms();
|
||||
int[] positions = query.getPositions();
|
||||
for (int i = 0; i < terms.length; ++i) {
|
||||
builder.add(terms[i], positions[i]);
|
||||
}
|
||||
builder.setSlop(slop);
|
||||
query = builder.build();
|
||||
|
||||
MockDirectoryWrapper ramDir = new MockDirectoryWrapper(random(), new RAMDirectory());
|
||||
RandomIndexWriter writer = new RandomIndexWriter(random(), ramDir, new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false));
|
||||
|
@ -168,12 +175,8 @@ public class TestSloppyPhraseQuery extends LuceneTestCase {
|
|||
}
|
||||
|
||||
private static PhraseQuery makePhraseQuery(String terms) {
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
String[] t = terms.split(" +");
|
||||
for (int i=0; i<t.length; i++) {
|
||||
query.add(new Term("f", t[i]));
|
||||
}
|
||||
return query;
|
||||
return new PhraseQuery("f", t);
|
||||
}
|
||||
|
||||
static class MaxFreqCollector extends SimpleCollector {
|
||||
|
@ -242,16 +245,18 @@ public class TestSloppyPhraseQuery extends LuceneTestCase {
|
|||
IndexReader ir = iw.getReader();
|
||||
iw.close();
|
||||
IndexSearcher is = newSearcher(ir);
|
||||
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("lyrics", "drug"), 1);
|
||||
builder.add(new Term("lyrics", "drug"), 4);
|
||||
PhraseQuery pq = builder.build();
|
||||
// "drug the drug"~1
|
||||
pq.add(new Term("lyrics", "drug"), 1);
|
||||
pq.add(new Term("lyrics", "drug"), 4);
|
||||
pq.setSlop(0);
|
||||
assertEquals(1, is.search(pq, 4).totalHits);
|
||||
pq.setSlop(1);
|
||||
builder.setSlop(1);
|
||||
pq = builder.build();
|
||||
assertEquals(3, is.search(pq, 4).totalHits);
|
||||
pq.setSlop(2);
|
||||
builder.setSlop(2);
|
||||
pq = builder.build();
|
||||
assertEquals(4, is.search(pq, 4).totalHits);
|
||||
ir.close();
|
||||
dir.close();
|
||||
|
@ -270,11 +275,12 @@ public class TestSloppyPhraseQuery extends LuceneTestCase {
|
|||
iw.close();
|
||||
|
||||
IndexSearcher is = newSearcher(ir);
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("lyrics", "drug"), 1);
|
||||
builder.add(new Term("lyrics", "drug"), 3);
|
||||
builder.setSlop(1);
|
||||
PhraseQuery pq = builder.build();
|
||||
// "drug the drug"~1
|
||||
pq.add(new Term("lyrics", "drug"), 1);
|
||||
pq.add(new Term("lyrics", "drug"), 3);
|
||||
pq.setSlop(1);
|
||||
assertSaneScoring(pq, is);
|
||||
ir.close();
|
||||
dir.close();
|
||||
|
@ -324,11 +330,12 @@ public class TestSloppyPhraseQuery extends LuceneTestCase {
|
|||
|
||||
IndexSearcher is = newSearcher(ir);
|
||||
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term("lyrics", "drug"), 1);
|
||||
builder.add(new Term("lyrics", "drug"), 4);
|
||||
builder.setSlop(5);
|
||||
PhraseQuery pq = builder.build();
|
||||
// "drug the drug"~5
|
||||
pq.add(new Term("lyrics", "drug"), 1);
|
||||
pq.add(new Term("lyrics", "drug"), 3);
|
||||
pq.setSlop(5);
|
||||
assertSaneScoring(pq, is);
|
||||
ir.close();
|
||||
dir.close();
|
||||
|
|
|
@ -31,15 +31,8 @@ public class TestSloppyPhraseQuery2 extends SearchEquivalenceTestBase {
|
|||
Term t1 = randomTerm();
|
||||
Term t2 = randomTerm();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2);
|
||||
q1.setSlop(i);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t1);
|
||||
q2.add(t2);
|
||||
q1.setSlop(i);
|
||||
q2.setSlop(i+1);
|
||||
PhraseQuery q1 = new PhraseQuery(i, t1.field(), t1.bytes(), t2.bytes());
|
||||
PhraseQuery q2 = new PhraseQuery(i + 1, t1.field(), t1.bytes(), t2.bytes());
|
||||
assertSubsetOf(q1, q2);
|
||||
}
|
||||
}
|
||||
|
@ -49,14 +42,13 @@ public class TestSloppyPhraseQuery2 extends SearchEquivalenceTestBase {
|
|||
Term t1 = randomTerm();
|
||||
Term t2 = randomTerm();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2, 2);
|
||||
q1.setSlop(i);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t1);
|
||||
q2.add(t2, 2);
|
||||
q2.setSlop(i+1);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(t1, 0);
|
||||
builder.add(t2, 2);
|
||||
builder.setSlop(i);
|
||||
PhraseQuery q1 = builder.build();
|
||||
builder.setSlop(i + 1);
|
||||
PhraseQuery q2 = builder.build();
|
||||
assertSubsetOf(q1, q2);
|
||||
}
|
||||
}
|
||||
|
@ -67,16 +59,9 @@ public class TestSloppyPhraseQuery2 extends SearchEquivalenceTestBase {
|
|||
Term t2 = randomTerm();
|
||||
Term t3 = randomTerm();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2);
|
||||
q1.add(t3);
|
||||
q1.setSlop(i);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t1);
|
||||
q2.add(t2);
|
||||
q2.add(t3);
|
||||
q2.setSlop(i+1);
|
||||
PhraseQuery q1 = new PhraseQuery(i, t1.field(), t1.bytes(), t2.bytes(), t3.bytes());
|
||||
PhraseQuery q2 = new PhraseQuery(i + 1, t1.field(), t1.bytes(), t2.bytes(), t3.bytes());
|
||||
assertSubsetOf(q1, q2);
|
||||
assertSubsetOf(q1, q2);
|
||||
}
|
||||
}
|
||||
|
@ -89,16 +74,14 @@ public class TestSloppyPhraseQuery2 extends SearchEquivalenceTestBase {
|
|||
int pos1 = 1 + random().nextInt(3);
|
||||
int pos2 = pos1 + 1 + random().nextInt(3);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t1);
|
||||
q1.add(t2, pos1);
|
||||
q1.add(t3, pos2);
|
||||
q1.setSlop(i);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t1);
|
||||
q2.add(t2, pos1);
|
||||
q2.add(t3, pos2);
|
||||
q2.setSlop(i+1);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(t1, 0);
|
||||
builder.add(t2, pos1);
|
||||
builder.add(t3, pos2);
|
||||
builder.setSlop(i);
|
||||
PhraseQuery q1 = builder.build();
|
||||
builder.setSlop(i + 1);
|
||||
PhraseQuery q2 = builder.build();
|
||||
assertSubsetOf(q1, q2);
|
||||
}
|
||||
}
|
||||
|
@ -107,14 +90,8 @@ public class TestSloppyPhraseQuery2 extends SearchEquivalenceTestBase {
|
|||
public void testRepetitiveIncreasingSloppiness() throws Exception {
|
||||
Term t = randomTerm();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t);
|
||||
q1.add(t);
|
||||
q1.setSlop(i);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t);
|
||||
q2.add(t);
|
||||
q2.setSlop(i+1);
|
||||
PhraseQuery q1 = new PhraseQuery(i, t.field(), t.bytes(), t.bytes());
|
||||
PhraseQuery q2 = new PhraseQuery(i + 1, t.field(), t.bytes(), t.bytes());
|
||||
assertSubsetOf(q1, q2);
|
||||
}
|
||||
}
|
||||
|
@ -123,14 +100,13 @@ public class TestSloppyPhraseQuery2 extends SearchEquivalenceTestBase {
|
|||
public void testRepetitiveIncreasingSloppinessWithHoles() throws Exception {
|
||||
Term t = randomTerm();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t);
|
||||
q1.add(t, 2);
|
||||
q1.setSlop(i);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t);
|
||||
q2.add(t, 2);
|
||||
q2.setSlop(i+1);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(t, 0);
|
||||
builder.add(t, 2);
|
||||
builder.setSlop(i);
|
||||
PhraseQuery q1 = builder.build();
|
||||
builder.setSlop(i + 1);
|
||||
PhraseQuery q2 = builder.build();
|
||||
assertSubsetOf(q1, q2);
|
||||
}
|
||||
}
|
||||
|
@ -139,16 +115,9 @@ public class TestSloppyPhraseQuery2 extends SearchEquivalenceTestBase {
|
|||
public void testRepetitiveIncreasingSloppiness3() throws Exception {
|
||||
Term t = randomTerm();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t);
|
||||
q1.add(t);
|
||||
q1.add(t);
|
||||
q1.setSlop(i);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t);
|
||||
q2.add(t);
|
||||
q2.add(t);
|
||||
q2.setSlop(i+1);
|
||||
PhraseQuery q1 = new PhraseQuery(i, t.field(), t.bytes(), t.bytes(), t.bytes());
|
||||
PhraseQuery q2 = new PhraseQuery(i + 1, t.field(), t.bytes(), t.bytes(), t.bytes());
|
||||
assertSubsetOf(q1, q2);
|
||||
assertSubsetOf(q1, q2);
|
||||
}
|
||||
}
|
||||
|
@ -159,16 +128,15 @@ public class TestSloppyPhraseQuery2 extends SearchEquivalenceTestBase {
|
|||
int pos1 = 1 + random().nextInt(3);
|
||||
int pos2 = pos1 + 1 + random().nextInt(3);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PhraseQuery q1 = new PhraseQuery();
|
||||
q1.add(t);
|
||||
q1.add(t, pos1);
|
||||
q1.add(t, pos2);
|
||||
q1.setSlop(i);
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t);
|
||||
q2.add(t, pos1);
|
||||
q2.add(t, pos2);
|
||||
q2.setSlop(i+1);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(t, 0);
|
||||
builder.add(t, pos1);
|
||||
builder.add(t, pos2);
|
||||
builder.setSlop(i);
|
||||
PhraseQuery q1 = builder.build();
|
||||
builder.setSlop(i + 1);
|
||||
PhraseQuery q2 = builder.build();
|
||||
assertSubsetOf(q1, q2);
|
||||
assertSubsetOf(q1, q2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,9 +192,7 @@ public class TestSubScorerFreqs extends LuceneTestCase {
|
|||
|
||||
@Test
|
||||
public void testPhraseQuery() throws Exception {
|
||||
PhraseQuery q = new PhraseQuery();
|
||||
q.add(new Term("f", "b"));
|
||||
q.add(new Term("f", "c"));
|
||||
PhraseQuery q = new PhraseQuery("f", "b", "c");
|
||||
CountingCollector c = new CountingCollector(TopScoreDocCollector.create(10));
|
||||
s.search(q, c);
|
||||
final int maxDocs = s.getIndexReader().maxDoc();
|
||||
|
|
|
@ -113,18 +113,14 @@ public class TestBasics extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testPhrase() throws Exception {
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term("field", "seventy"));
|
||||
query.add(new Term("field", "seven"));
|
||||
PhraseQuery query = new PhraseQuery("field", "seventy", "seven");
|
||||
checkHits(query, new int[]
|
||||
{77, 177, 277, 377, 477, 577, 677, 777, 877,
|
||||
977, 1077, 1177, 1277, 1377, 1477, 1577, 1677, 1777, 1877, 1977});
|
||||
}
|
||||
|
||||
public void testPhrase2() throws Exception {
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term("field", "seventish"));
|
||||
query.add(new Term("field", "sevenon"));
|
||||
PhraseQuery query = new PhraseQuery("field", "seventish", "sevenon");
|
||||
checkHits(query, new int[] {});
|
||||
}
|
||||
|
||||
|
|
|
@ -153,9 +153,7 @@ public class TestSpanSearchEquivalence extends SearchEquivalenceTestBase {
|
|||
spanQuery(new SpanTermQuery(t2))
|
||||
};
|
||||
SpanQuery q1 = spanQuery(new SpanNearQuery(subquery, 0, true));
|
||||
PhraseQuery q2 = new PhraseQuery();
|
||||
q2.add(t1);
|
||||
q2.add(t2);
|
||||
PhraseQuery q2 = new PhraseQuery(t1.field(), t1.bytes(), t2.bytes());
|
||||
assertSameSet(q1, q2);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ package org.apache.lucene.util;
|
|||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.MockAnalyzer;
|
||||
|
@ -100,10 +98,10 @@ public class TestQueryBuilder extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testPhraseQueryPositionIncrements() throws Exception {
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
expected.add(new Term("field", "1"));
|
||||
expected.add(new Term("field", "2"), 2);
|
||||
|
||||
PhraseQuery.Builder pqBuilder = new PhraseQuery.Builder();
|
||||
pqBuilder.add(new Term("field", "1"), 0);
|
||||
pqBuilder.add(new Term("field", "2"), 2);
|
||||
PhraseQuery expected = pqBuilder.build();
|
||||
CharacterRunAutomaton stopList = new CharacterRunAutomaton(new RegExp("[sS][tT][oO][pP]").toAutomaton());
|
||||
|
||||
Analyzer analyzer = new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false, stopList);
|
||||
|
@ -219,9 +217,7 @@ public class TestQueryBuilder extends LuceneTestCase {
|
|||
// individual CJK chars as terms
|
||||
SimpleCJKAnalyzer analyzer = new SimpleCJKAnalyzer();
|
||||
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
expected.add(new Term("field", "中"));
|
||||
expected.add(new Term("field", "国"));
|
||||
PhraseQuery expected = new PhraseQuery("field", "中", "国");
|
||||
|
||||
QueryBuilder builder = new QueryBuilder(analyzer);
|
||||
assertEquals(expected, builder.createPhraseQuery("field", "中国"));
|
||||
|
@ -231,10 +227,7 @@ public class TestQueryBuilder extends LuceneTestCase {
|
|||
// individual CJK chars as terms
|
||||
SimpleCJKAnalyzer analyzer = new SimpleCJKAnalyzer();
|
||||
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
expected.setSlop(3);
|
||||
expected.add(new Term("field", "中"));
|
||||
expected.add(new Term("field", "国"));
|
||||
PhraseQuery expected = new PhraseQuery(3, "field", "中", "国");
|
||||
|
||||
QueryBuilder builder = new QueryBuilder(analyzer);
|
||||
assertEquals(expected, builder.createPhraseQuery("field", "中国", 3));
|
||||
|
|
|
@ -232,13 +232,14 @@ public class FieldQuery {
|
|||
}
|
||||
}
|
||||
if( overlap && src.length - i < dest.length ){
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
PhraseQuery.Builder pqBuilder = new PhraseQuery.Builder();
|
||||
for( Term srcTerm : src )
|
||||
pq.add( srcTerm );
|
||||
pqBuilder.add( srcTerm );
|
||||
for( int k = src.length - i; k < dest.length; k++ ){
|
||||
pq.add( new Term( src[0].field(), dest[k].text() ) );
|
||||
pqBuilder.add( new Term( src[0].field(), dest[k].text() ) );
|
||||
}
|
||||
pq.setSlop( slop );
|
||||
pqBuilder.setSlop( slop );
|
||||
PhraseQuery pq = pqBuilder.build();
|
||||
pq.setBoost( boost );
|
||||
if(!expandQueries.contains( pq ) )
|
||||
expandQueries.add( pq );
|
||||
|
|
|
@ -70,10 +70,7 @@ public class HighlighterPhraseTest extends LuceneTestCase {
|
|||
try {
|
||||
assertEquals(1, indexReader.numDocs());
|
||||
final IndexSearcher indexSearcher = newSearcher(indexReader);
|
||||
final PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD, "fox"));
|
||||
phraseQuery.add(new Term(FIELD, "jumped"));
|
||||
phraseQuery.setSlop(0);
|
||||
final PhraseQuery phraseQuery = new PhraseQuery(FIELD, "fox", "jumped");
|
||||
TopDocs hits = indexSearcher.search(phraseQuery, 1);
|
||||
assertEquals(1, hits.totalHits);
|
||||
final Highlighter highlighter = new Highlighter(
|
||||
|
@ -178,10 +175,7 @@ public class HighlighterPhraseTest extends LuceneTestCase {
|
|||
try {
|
||||
assertEquals(1, indexReader.numDocs());
|
||||
final IndexSearcher indexSearcher = newSearcher(indexReader);
|
||||
final PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD, "did"));
|
||||
phraseQuery.add(new Term(FIELD, "jump"));
|
||||
phraseQuery.setSlop(0);
|
||||
final PhraseQuery phraseQuery = new PhraseQuery(FIELD, "did", "jump");
|
||||
TopDocs hits = indexSearcher.search(phraseQuery, 1);
|
||||
assertEquals(0, hits.totalHits);
|
||||
final Highlighter highlighter = new Highlighter(
|
||||
|
@ -218,10 +212,7 @@ public class HighlighterPhraseTest extends LuceneTestCase {
|
|||
try {
|
||||
assertEquals(1, indexReader.numDocs());
|
||||
final IndexSearcher indexSearcher = newSearcher(indexReader);
|
||||
final PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD, "did"));
|
||||
phraseQuery.add(new Term(FIELD, "jump"));
|
||||
phraseQuery.setSlop(1);
|
||||
final PhraseQuery phraseQuery = new PhraseQuery(1, FIELD, "did", "jump");
|
||||
TopDocs hits = indexSearcher.search(phraseQuery, 1);
|
||||
assertEquals(1, hits.totalHits);
|
||||
final Highlighter highlighter = new Highlighter(
|
||||
|
|
|
@ -17,8 +17,6 @@ package org.apache.lucene.search.highlight;
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -31,6 +29,9 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.BaseTokenStreamTestCase;
|
||||
import org.apache.lucene.analysis.CachingTokenFilter;
|
||||
|
@ -70,6 +71,7 @@ import org.apache.lucene.search.MultiPhraseQuery;
|
|||
import org.apache.lucene.search.MultiTermQuery;
|
||||
import org.apache.lucene.search.NumericRangeQuery;
|
||||
import org.apache.lucene.search.PhraseQuery;
|
||||
import org.apache.lucene.search.PhraseQuery.Builder;
|
||||
import org.apache.lucene.search.PrefixQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.QueryWrapperFilter;
|
||||
|
@ -84,11 +86,11 @@ import org.apache.lucene.search.join.BitDocIdSetFilter;
|
|||
import org.apache.lucene.search.join.ScoreMode;
|
||||
import org.apache.lucene.search.join.ToChildBlockJoinQuery;
|
||||
import org.apache.lucene.search.join.ToParentBlockJoinQuery;
|
||||
import org.apache.lucene.search.payloads.SpanPayloadCheckQuery;
|
||||
import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
|
||||
import org.apache.lucene.search.spans.SpanNearQuery;
|
||||
import org.apache.lucene.search.spans.SpanNotQuery;
|
||||
import org.apache.lucene.search.spans.SpanOrQuery;
|
||||
import org.apache.lucene.search.payloads.SpanPayloadCheckQuery;
|
||||
import org.apache.lucene.search.spans.SpanQuery;
|
||||
import org.apache.lucene.search.spans.SpanTermQuery;
|
||||
import org.apache.lucene.store.Directory;
|
||||
|
@ -165,9 +167,7 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
}
|
||||
|
||||
public void testQueryScorerHits() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD_NAME, "very"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "long"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(FIELD_NAME, "very", "long");
|
||||
|
||||
query = phraseQuery;
|
||||
searcher = newSearcher(reader);
|
||||
|
@ -289,10 +289,7 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
// highlighted
|
||||
// regardless of the field name.
|
||||
|
||||
PhraseQuery q = new PhraseQuery();
|
||||
q.setSlop(3);
|
||||
q.add(new Term(FIELD_NAME, "world"));
|
||||
q.add(new Term(FIELD_NAME, "flatland"));
|
||||
PhraseQuery q = new PhraseQuery(3, FIELD_NAME, "world", "flatland");
|
||||
|
||||
String expected = "I call our <B>world</B> <B>Flatland</B>, not because we call it so,";
|
||||
String observed = highlightField(q, "SOME_FIELD_NAME", s1);
|
||||
|
@ -305,10 +302,7 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
// when the query field name differs from the name of the field being
|
||||
// highlighted,
|
||||
// which in this example happens to be the default field name.
|
||||
q = new PhraseQuery();
|
||||
q.setSlop(3);
|
||||
q.add(new Term("text", "world"));
|
||||
q.add(new Term("text", "flatland"));
|
||||
q = new PhraseQuery(3, "text", "world", "flatland");
|
||||
|
||||
expected = s1;
|
||||
observed = highlightField(q, FIELD_NAME, s1);
|
||||
|
@ -362,27 +356,13 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
String f1 = "f1";
|
||||
String f2 = "f2";
|
||||
|
||||
PhraseQuery f1ph1 = new PhraseQuery();
|
||||
f1ph1.add(new Term(f1, "a"));
|
||||
f1ph1.add(new Term(f1, "b"));
|
||||
f1ph1.add(new Term(f1, "c"));
|
||||
f1ph1.add(new Term(f1, "d"));
|
||||
PhraseQuery f1ph1 = new PhraseQuery(f1, "a", "b", "c", "d");
|
||||
|
||||
PhraseQuery f2ph1 = new PhraseQuery();
|
||||
f2ph1.add(new Term(f2, "a"));
|
||||
f2ph1.add(new Term(f2, "b"));
|
||||
f2ph1.add(new Term(f2, "c"));
|
||||
f2ph1.add(new Term(f2, "d"));
|
||||
PhraseQuery f2ph1 = new PhraseQuery(f2, "a", "b", "c", "d");
|
||||
|
||||
PhraseQuery f1ph2 = new PhraseQuery();
|
||||
f1ph2.add(new Term(f1, "b"));
|
||||
f1ph2.add(new Term(f1, "c"));
|
||||
f1ph2.add(new Term(f1, "g"));
|
||||
PhraseQuery f1ph2 = new PhraseQuery(f1, "b", "c", "g");
|
||||
|
||||
PhraseQuery f2ph2 = new PhraseQuery();
|
||||
f2ph2.add(new Term(f2, "b"));
|
||||
f2ph2.add(new Term(f2, "c"));
|
||||
f2ph2.add(new Term(f2, "g"));
|
||||
PhraseQuery f2ph2 = new PhraseQuery(f2, "b", "c", "g");
|
||||
|
||||
BooleanQuery booleanQuery = new BooleanQuery();
|
||||
BooleanQuery leftChild = new BooleanQuery();
|
||||
|
@ -409,10 +389,11 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
}
|
||||
|
||||
public void testSimpleQueryScorerPhraseHighlighting() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD_NAME, "very"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "long"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "contains"), 3);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term(FIELD_NAME, "very"), 0);
|
||||
builder.add(new Term(FIELD_NAME, "long"), 1);
|
||||
builder.add(new Term(FIELD_NAME, "contains"), 3);
|
||||
PhraseQuery phraseQuery = builder.build();
|
||||
doSearching(phraseQuery);
|
||||
|
||||
int maxNumFragmentsRequired = 2;
|
||||
|
@ -438,11 +419,12 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
|
||||
numHighlights = 0;
|
||||
|
||||
phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD_NAME, "piece"), 1);
|
||||
phraseQuery.add(new Term(FIELD_NAME, "text"), 3);
|
||||
phraseQuery.add(new Term(FIELD_NAME, "refers"), 4);
|
||||
phraseQuery.add(new Term(FIELD_NAME, "kennedy"), 6);
|
||||
builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term(FIELD_NAME, "piece"), 1);
|
||||
builder.add(new Term(FIELD_NAME, "text"), 3);
|
||||
builder.add(new Term(FIELD_NAME, "refers"), 4);
|
||||
builder.add(new Term(FIELD_NAME, "kennedy"), 6);
|
||||
phraseQuery = builder.build();
|
||||
|
||||
doSearching(phraseQuery);
|
||||
|
||||
|
@ -469,11 +451,12 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
|
||||
numHighlights = 0;
|
||||
|
||||
phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD_NAME, "lets"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "lets"), 4);
|
||||
phraseQuery.add(new Term(FIELD_NAME, "lets"), 8);
|
||||
phraseQuery.add(new Term(FIELD_NAME, "lets"), 12);
|
||||
builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term(FIELD_NAME, "lets"), 0);
|
||||
builder.add(new Term(FIELD_NAME, "lets"), 4);
|
||||
builder.add(new Term(FIELD_NAME, "lets"), 8);
|
||||
builder.add(new Term(FIELD_NAME, "lets"), 12);
|
||||
phraseQuery = builder.build();
|
||||
|
||||
doSearching(phraseQuery);
|
||||
|
||||
|
@ -661,11 +644,7 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
}
|
||||
|
||||
public void testSimpleQueryScorerPhraseHighlighting2() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.setSlop(5);
|
||||
phraseQuery.add(new Term(FIELD_NAME, "text"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "piece"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "long"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(5, FIELD_NAME, "text", "piece", "long");
|
||||
doSearching(phraseQuery);
|
||||
|
||||
int maxNumFragmentsRequired = 2;
|
||||
|
@ -690,10 +669,7 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
}
|
||||
|
||||
public void testSimpleQueryScorerPhraseHighlighting3() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD_NAME, "x"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "y"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "z"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(FIELD_NAME, "x", "y", "z");
|
||||
doSearching(phraseQuery);
|
||||
|
||||
int maxNumFragmentsRequired = 2;
|
||||
|
@ -718,11 +694,12 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
}
|
||||
|
||||
public void testSimpleSpanFragmenter() throws Exception {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD_NAME, "piece"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "text"), 2);
|
||||
phraseQuery.add(new Term(FIELD_NAME, "very"), 5);
|
||||
phraseQuery.add(new Term(FIELD_NAME, "long"), 6);
|
||||
Builder builder = new PhraseQuery.Builder();
|
||||
builder.add(new Term(FIELD_NAME, "piece"), 0);
|
||||
builder.add(new Term(FIELD_NAME, "text"), 2);
|
||||
builder.add(new Term(FIELD_NAME, "very"), 5);
|
||||
builder.add(new Term(FIELD_NAME, "long"), 6);
|
||||
PhraseQuery phraseQuery = builder.build();
|
||||
doSearching(phraseQuery);
|
||||
|
||||
int maxNumFragmentsRequired = 2;
|
||||
|
@ -744,9 +721,7 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
|
||||
}
|
||||
|
||||
phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD_NAME, "been"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "shot"));
|
||||
phraseQuery = new PhraseQuery(FIELD_NAME, "been", "shot");
|
||||
|
||||
doSearching(query);
|
||||
|
||||
|
@ -773,10 +748,7 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
BooleanQuery booleanQuery = new BooleanQuery();
|
||||
booleanQuery.add(new TermQuery(new Term(FIELD_NAME, "y")), Occur.SHOULD);
|
||||
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD_NAME, "x"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "y"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "z"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(FIELD_NAME, "x", "y", "z");
|
||||
booleanQuery.add(phraseQuery, Occur.SHOULD);
|
||||
|
||||
doSearching(booleanQuery);
|
||||
|
@ -1134,9 +1106,7 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
@Override
|
||||
public void run() throws Exception {
|
||||
numHighlights = 0;
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(FIELD_NAME, "john"));
|
||||
phraseQuery.add(new Term(FIELD_NAME, "kennedy"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(FIELD_NAME, "john", "kennedy");
|
||||
doSearching(phraseQuery);
|
||||
doStandardHighlights(analyzer, searcher, hits, query, HighlighterTest.this);
|
||||
// Currently highlights "John" and "Kennedy" separately
|
||||
|
@ -1217,9 +1187,7 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
|
|||
@Override
|
||||
public void run() throws Exception {
|
||||
numHighlights = 0;
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("contents", "john"));
|
||||
pq.add(new Term("contents", "kennedy"));
|
||||
PhraseQuery pq = new PhraseQuery("contents", "john", "kennedy");
|
||||
BooleanQuery bq = new BooleanQuery();
|
||||
bq.add(pq, Occur.MUST);
|
||||
bq.add(TermRangeQuery.newStringRange("contents", "john", "john", true, true), Occur.FILTER);
|
||||
|
|
|
@ -58,9 +58,7 @@ public class MissesTest extends LuceneTestCase {
|
|||
|
||||
public void testPhraseQuery() throws IOException, InvalidTokenOffsetsException {
|
||||
try (Analyzer analyzer = new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false)) {
|
||||
final PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term("test", "foo"));
|
||||
query.add(new Term("test", "bar"));
|
||||
final PhraseQuery query = new PhraseQuery("test", "foo", "bar");
|
||||
final Highlighter highlighter = new Highlighter(new SimpleHTMLFormatter(), new QueryScorer(query));
|
||||
assertEquals("this is a <B>foo</B> <B>bar</B> example",
|
||||
highlighter.getBestFragment(analyzer, "test", "this is a foo bar example"));
|
||||
|
|
|
@ -447,9 +447,7 @@ public class TestPostingsHighlighter extends LuceneTestCase {
|
|||
IndexReader ir = iw.getReader();
|
||||
iw.close();
|
||||
IndexSearcher searcher = newSearcher(ir);
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term("body", "buddhist"));
|
||||
query.add(new Term("body", "origins"));
|
||||
PhraseQuery query = new PhraseQuery("body", "buddhist", "origins");
|
||||
TopDocs topDocs = searcher.search(query, 10);
|
||||
assertEquals(1, topDocs.totalHits);
|
||||
PostingsHighlighter highlighter = new PostingsHighlighter();
|
||||
|
@ -477,9 +475,7 @@ public class TestPostingsHighlighter extends LuceneTestCase {
|
|||
IndexReader ir = iw.getReader();
|
||||
iw.close();
|
||||
IndexSearcher searcher = newSearcher(ir);
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term("body", "curious"));
|
||||
query.add(new Term("body", "george"));
|
||||
PhraseQuery query = new PhraseQuery("body", "curious", "george");
|
||||
TopDocs topDocs = searcher.search(query, 10);
|
||||
assertEquals(1, topDocs.totalHits);
|
||||
PostingsHighlighter highlighter = new PostingsHighlighter();
|
||||
|
|
|
@ -138,12 +138,8 @@ public abstract class AbstractTestCase extends LuceneTestCase {
|
|||
}
|
||||
|
||||
protected Query pq( float boost, int slop, String field, String... texts ){
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
for( String text : texts ){
|
||||
query.add( new Term( field, text ) );
|
||||
}
|
||||
PhraseQuery query = new PhraseQuery(slop, field, texts);
|
||||
query.setBoost( boost );
|
||||
query.setSlop( slop );
|
||||
return query;
|
||||
}
|
||||
|
||||
|
@ -188,11 +184,7 @@ public abstract class AbstractTestCase extends LuceneTestCase {
|
|||
}
|
||||
|
||||
protected PhraseQuery toPhraseQuery(List<BytesRef> bytesRefs, String field) {
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
for (BytesRef bytesRef : bytesRefs) {
|
||||
phraseQuery.add(new Term(field, bytesRef));
|
||||
}
|
||||
return phraseQuery;
|
||||
return new PhraseQuery(field, bytesRefs.toArray(new BytesRef[0]));
|
||||
}
|
||||
|
||||
static final class BigramAnalyzer extends Analyzer {
|
||||
|
|
|
@ -148,9 +148,7 @@ public class FastVectorHighlighterTest extends LuceneTestCase {
|
|||
}
|
||||
|
||||
{
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term(field, "internet"));
|
||||
query.add(new Term(field, "explorer"));
|
||||
PhraseQuery query = new PhraseQuery(field, "internet", "explorer");
|
||||
FieldQuery fieldQuery = highlighter.getFieldQuery(query, reader);
|
||||
String[] bestFragments = highlighter.getBestFragments(fieldQuery, reader,
|
||||
docId, field, 128, 1);
|
||||
|
@ -197,11 +195,7 @@ public class FastVectorHighlighterTest extends LuceneTestCase {
|
|||
}
|
||||
{
|
||||
BooleanQuery query = new BooleanQuery();
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term(field, "test"));
|
||||
pq.add(new Term(field, "foo"));
|
||||
pq.add(new Term(field, "highlighed"));
|
||||
pq.setSlop(5);
|
||||
PhraseQuery pq = new PhraseQuery(5, field, "test", "foo", "highlighed");
|
||||
query.add(new TermQuery(new Term(field, "foo")), Occur.MUST);
|
||||
query.add(pq, Occur.MUST);
|
||||
query.add(new TermQuery(new Term(field, "highlighed")), Occur.MUST);
|
||||
|
@ -218,11 +212,7 @@ public class FastVectorHighlighterTest extends LuceneTestCase {
|
|||
|
||||
}
|
||||
{
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term(field, "test"));
|
||||
query.add(new Term(field, "foo"));
|
||||
query.add(new Term(field, "highlighed"));
|
||||
query.setSlop(3);
|
||||
PhraseQuery query = new PhraseQuery(3, field, "test", "foo", "highlighed");
|
||||
FieldQuery fieldQuery = highlighter.getFieldQuery(query, reader);
|
||||
String[] bestFragments = highlighter.getBestFragments(fieldQuery, reader,
|
||||
docId, field, 18, 1);
|
||||
|
@ -236,11 +226,7 @@ public class FastVectorHighlighterTest extends LuceneTestCase {
|
|||
|
||||
}
|
||||
{
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term(field, "test"));
|
||||
query.add(new Term(field, "foo"));
|
||||
query.add(new Term(field, "highlighted"));
|
||||
query.setSlop(30);
|
||||
PhraseQuery query = new PhraseQuery(30, field, "test", "foo", "highlighed");
|
||||
FieldQuery fieldQuery = highlighter.getFieldQuery(query, reader);
|
||||
String[] bestFragments = highlighter.getBestFragments(fieldQuery, reader,
|
||||
docId, field, 18, 1);
|
||||
|
@ -248,11 +234,7 @@ public class FastVectorHighlighterTest extends LuceneTestCase {
|
|||
}
|
||||
{
|
||||
BooleanQuery query = new BooleanQuery();
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term(field, "test"));
|
||||
pq.add(new Term(field, "foo"));
|
||||
pq.add(new Term(field, "highlighed"));
|
||||
pq.setSlop(5);
|
||||
PhraseQuery pq = new PhraseQuery(5, field, "test", "foo", "highlighed");
|
||||
BooleanQuery inner = new BooleanQuery();
|
||||
inner.add(pq, Occur.MUST);
|
||||
inner.add(new TermQuery(new Term(field, "foo")), Occur.MUST);
|
||||
|
@ -567,23 +549,13 @@ public class FastVectorHighlighterTest extends LuceneTestCase {
|
|||
int docId = 0;
|
||||
|
||||
// query1: match
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("field", "test"));
|
||||
pq.add(new Term("field", "http"));
|
||||
pq.add(new Term("field", "www"));
|
||||
pq.add(new Term("field", "facebook"));
|
||||
pq.add(new Term("field", "com"));
|
||||
PhraseQuery pq = new PhraseQuery("field", "test", "http", "www", "facebook", "com");
|
||||
FieldQuery fieldQuery = highlighter.getFieldQuery(pq, reader);
|
||||
String[] bestFragments = highlighter.getBestFragments(fieldQuery, reader, docId, "field", 54, 1);
|
||||
assertEquals("<b>Test: http://www.facebook.com</b>", bestFragments[0]);
|
||||
|
||||
// query2: match
|
||||
PhraseQuery pq2 = new PhraseQuery();
|
||||
pq2.add(new Term("field", "test"));
|
||||
pq2.add(new Term("field", "httpwwwfacebookcom"));
|
||||
pq2.add(new Term("field", "www"));
|
||||
pq2.add(new Term("field", "facebook"));
|
||||
pq2.add(new Term("field", "com"));
|
||||
PhraseQuery pq2 = new PhraseQuery("field", "test", "httpwwwfacebookcom", "www", "facebook", "com");
|
||||
fieldQuery = highlighter.getFieldQuery(pq2, reader);
|
||||
bestFragments = highlighter.getBestFragments(fieldQuery, reader, docId, "field", 54, 1);
|
||||
assertEquals("<b>Test: http://www.facebook.com</b>", bestFragments[0]);
|
||||
|
@ -692,11 +664,7 @@ public class FastVectorHighlighterTest extends LuceneTestCase {
|
|||
if ( terms.length == 1 ) {
|
||||
q = new TermQuery( new Term( field, terms[ 0 ] ) );
|
||||
} else {
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
for ( String term: terms ) {
|
||||
pq.add( new Term( field, term ) );
|
||||
}
|
||||
q = pq;
|
||||
q = new PhraseQuery(field, terms);
|
||||
}
|
||||
q.setBoost( boost );
|
||||
return q;
|
||||
|
|
|
@ -48,9 +48,7 @@ public class SimpleFragListBuilderTest extends AbstractTestCase {
|
|||
public void testSmallerFragSizeThanPhraseQuery() throws Exception {
|
||||
SimpleFragListBuilder sflb = new SimpleFragListBuilder();
|
||||
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(F, "abcdefgh"));
|
||||
phraseQuery.add(new Term(F, "jklmnopqrs"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(F, "abcdefgh", "jklmnopqrs");
|
||||
|
||||
FieldFragList ffl = sflb.createFieldFragList( fpl(phraseQuery, "abcdefgh jklmnopqrs" ), sflb.minFragCharSize );
|
||||
assertEquals( 1, ffl.getFragInfos().size() );
|
||||
|
@ -120,9 +118,7 @@ public class SimpleFragListBuilderTest extends AbstractTestCase {
|
|||
public void testPhraseQuery() throws Exception {
|
||||
SimpleFragListBuilder sflb = new SimpleFragListBuilder();
|
||||
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.add(new Term(F, "a"));
|
||||
phraseQuery.add(new Term(F, "b"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(F, "a", "b");
|
||||
|
||||
FieldFragList ffl = sflb.createFieldFragList( fpl(phraseQuery, "c d e" ), 20 );
|
||||
assertEquals( 0, ffl.getFragInfos().size() );
|
||||
|
@ -138,10 +134,7 @@ public class SimpleFragListBuilderTest extends AbstractTestCase {
|
|||
public void testPhraseQuerySlop() throws Exception {
|
||||
SimpleFragListBuilder sflb = new SimpleFragListBuilder();
|
||||
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
phraseQuery.setSlop(1);
|
||||
phraseQuery.add(new Term(F, "a"));
|
||||
phraseQuery.add(new Term(F, "b"));
|
||||
PhraseQuery phraseQuery = new PhraseQuery(1, F, "a", "b");
|
||||
|
||||
FieldFragList ffl = sflb.createFieldFragList( fpl(phraseQuery, "a c b" ), 20 );
|
||||
assertEquals( 1, ffl.getFragInfos().size() );
|
||||
|
|
|
@ -410,16 +410,14 @@ public class TestMemoryIndexAgainstRAMDir extends BaseTokenStreamTestCase {
|
|||
LeafReader reader = (LeafReader) mindex.createSearcher().getIndexReader();
|
||||
TestUtil.checkReader(reader);
|
||||
assertEquals(7, reader.terms("field").getSumTotalTermFreq());
|
||||
PhraseQuery query = new PhraseQuery();
|
||||
query.add(new Term("field", "fox"));
|
||||
query.add(new Term("field", "jumps"));
|
||||
PhraseQuery query = new PhraseQuery("field", "fox", "jumps");
|
||||
assertTrue(mindex.search(query) > 0.1);
|
||||
mindex.reset();
|
||||
mockAnalyzer.setPositionIncrementGap(1 + random().nextInt(10));
|
||||
mindex.addField("field", "the quick brown fox", mockAnalyzer);
|
||||
mindex.addField("field", "jumps over the", mockAnalyzer);
|
||||
assertEquals(0, mindex.search(query), 0.00001f);
|
||||
query.setSlop(10);
|
||||
query = new PhraseQuery(10, "field", "fox", "jumps");
|
||||
assertTrue("posGap" + mockAnalyzer.getPositionIncrementGap("field") , mindex.search(query) > 0.0001);
|
||||
TestUtil.checkReader(mindex.createSearcher().getIndexReader());
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ public class MultiFieldQueryParser extends QueryParser
|
|||
q.setBoost(boost.floatValue());
|
||||
}
|
||||
}
|
||||
applySlop(q,slop);
|
||||
q = applySlop(q,slop);
|
||||
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
|
||||
}
|
||||
}
|
||||
|
@ -118,16 +118,26 @@ public class MultiFieldQueryParser extends QueryParser
|
|||
return getBooleanQuery(clauses, true);
|
||||
}
|
||||
Query q = super.getFieldQuery(field, queryText, true);
|
||||
applySlop(q,slop);
|
||||
q = applySlop(q,slop);
|
||||
return q;
|
||||
}
|
||||
|
||||
private void applySlop(Query q, int slop) {
|
||||
private Query applySlop(Query q, int slop) {
|
||||
if (q instanceof PhraseQuery) {
|
||||
((PhraseQuery) q).setSlop(slop);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.setSlop(slop);
|
||||
PhraseQuery pq = (PhraseQuery) q;
|
||||
org.apache.lucene.index.Term[] terms = pq.getTerms();
|
||||
int[] positions = pq.getPositions();
|
||||
for (int i = 0; i < terms.length; ++i) {
|
||||
builder.add(terms[i], positions[i]);
|
||||
}
|
||||
q = builder.build();
|
||||
q.setBoost(pq.getBoost());
|
||||
} else if (q instanceof MultiPhraseQuery) {
|
||||
((MultiPhraseQuery) q).setSlop(slop);
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -493,7 +493,16 @@ public abstract class QueryParserBase extends QueryBuilder implements CommonQuer
|
|||
Query query = getFieldQuery(field, queryText, true);
|
||||
|
||||
if (query instanceof PhraseQuery) {
|
||||
((PhraseQuery) query).setSlop(slop);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.setSlop(slop);
|
||||
PhraseQuery pq = (PhraseQuery) query;
|
||||
org.apache.lucene.index.Term[] terms = pq.getTerms();
|
||||
int[] positions = pq.getPositions();
|
||||
for (int i = 0; i < terms.length; ++i) {
|
||||
builder.add(terms[i], positions[i]);
|
||||
}
|
||||
query = builder.build();
|
||||
query.setBoost(pq.getBoost());
|
||||
}
|
||||
if (query instanceof MultiPhraseQuery) {
|
||||
((MultiPhraseQuery) query).setSlop(slop);
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
|
|||
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
|
||||
import org.apache.lucene.queryparser.flexible.core.nodes.TokenizedPhraseQueryNode;
|
||||
import org.apache.lucene.search.PhraseQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
|
||||
/**
|
||||
|
@ -38,10 +39,10 @@ public class PhraseQueryNodeBuilder implements StandardQueryBuilder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public PhraseQuery build(QueryNode queryNode) throws QueryNodeException {
|
||||
public Query build(QueryNode queryNode) throws QueryNodeException {
|
||||
TokenizedPhraseQueryNode phraseNode = (TokenizedPhraseQueryNode) queryNode;
|
||||
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
|
||||
List<QueryNode> children = phraseNode.getChildren();
|
||||
|
||||
|
@ -52,13 +53,12 @@ public class PhraseQueryNodeBuilder implements StandardQueryBuilder {
|
|||
.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
|
||||
FieldQueryNode termNode = (FieldQueryNode) child;
|
||||
|
||||
phraseQuery.add(termQuery.getTerm(), termNode.getPositionIncrement());
|
||||
|
||||
builder.add(termQuery.getTerm(), termNode.getPositionIncrement());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return phraseQuery;
|
||||
return builder.build();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,16 @@ public class SlopQueryNodeBuilder implements StandardQueryBuilder {
|
|||
QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
|
||||
|
||||
if (query instanceof PhraseQuery) {
|
||||
((PhraseQuery) query).setSlop(phraseSlopNode.getValue());
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
builder.setSlop(phraseSlopNode.getValue());
|
||||
PhraseQuery pq = (PhraseQuery) query;
|
||||
org.apache.lucene.index.Term[] terms = pq.getTerms();
|
||||
int[] positions = pq.getPositions();
|
||||
for (int i = 0; i < terms.length; ++i) {
|
||||
builder.add(terms[i], positions[i]);
|
||||
}
|
||||
query = builder.build();
|
||||
query.setBoost(pq.getBoost());
|
||||
|
||||
} else {
|
||||
((MultiPhraseQuery) query).setSlop(phraseSlopNode.getValue());
|
||||
|
|
|
@ -28,7 +28,13 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.lucene.analysis.*;
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.MockAnalyzer;
|
||||
import org.apache.lucene.analysis.MockTokenFilter;
|
||||
import org.apache.lucene.analysis.MockTokenizer;
|
||||
import org.apache.lucene.analysis.TokenFilter;
|
||||
import org.apache.lucene.analysis.TokenStream;
|
||||
import org.apache.lucene.analysis.Tokenizer;
|
||||
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
|
||||
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
|
||||
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
|
||||
|
@ -48,8 +54,8 @@ import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessor
|
|||
import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
|
||||
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler;
|
||||
import org.apache.lucene.queryparser.flexible.standard.nodes.WildcardQueryNode;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.FuzzyQuery;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
|
@ -401,9 +407,7 @@ public class TestQPHelper extends LuceneTestCase {
|
|||
// individual CJK chars as terms
|
||||
SimpleCJKAnalyzer analyzer = new SimpleCJKAnalyzer();
|
||||
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
expected.add(new Term("field", "中"));
|
||||
expected.add(new Term("field", "国"));
|
||||
PhraseQuery expected = new PhraseQuery("field", "中", "国");
|
||||
|
||||
assertEquals(expected, getQuery("\"中国\"", analyzer));
|
||||
}
|
||||
|
@ -412,10 +416,8 @@ public class TestQPHelper extends LuceneTestCase {
|
|||
// individual CJK chars as terms
|
||||
SimpleCJKAnalyzer analyzer = new SimpleCJKAnalyzer();
|
||||
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
PhraseQuery expected = new PhraseQuery("field", "中", "国");
|
||||
expected.setBoost(0.5f);
|
||||
expected.add(new Term("field", "中"));
|
||||
expected.add(new Term("field", "国"));
|
||||
|
||||
assertEquals(expected, getQuery("\"中国\"^0.5", analyzer));
|
||||
}
|
||||
|
@ -424,10 +426,7 @@ public class TestQPHelper extends LuceneTestCase {
|
|||
// individual CJK chars as terms
|
||||
SimpleCJKAnalyzer analyzer = new SimpleCJKAnalyzer();
|
||||
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
expected.setSlop(3);
|
||||
expected.add(new Term("field", "中"));
|
||||
expected.add(new Term("field", "国"));
|
||||
PhraseQuery expected = new PhraseQuery(3, "field", "中", "国");
|
||||
|
||||
assertEquals(expected, getQuery("\"中国\"~3", analyzer));
|
||||
}
|
||||
|
|
|
@ -103,42 +103,29 @@ public class TestSimpleQueryParser extends LuceneTestCase {
|
|||
|
||||
/** test a simple phrase */
|
||||
public void testPhrase() throws Exception {
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
expected.add(new Term("field", "foo"));
|
||||
expected.add(new Term("field", "bar"));
|
||||
PhraseQuery expected = new PhraseQuery("field", "foo", "bar");
|
||||
|
||||
assertEquals(expected, parse("\"foo bar\""));
|
||||
}
|
||||
|
||||
/** test a simple phrase with various slop settings */
|
||||
public void testPhraseWithSlop() throws Exception {
|
||||
PhraseQuery expectedWithSlop = new PhraseQuery();
|
||||
expectedWithSlop.add(new Term("field", "foo"));
|
||||
expectedWithSlop.add(new Term("field", "bar"));
|
||||
expectedWithSlop.setSlop(2);
|
||||
PhraseQuery expectedWithSlop = new PhraseQuery(2, "field", "foo", "bar");
|
||||
|
||||
assertEquals(expectedWithSlop, parse("\"foo bar\"~2"));
|
||||
|
||||
PhraseQuery expectedWithMultiDigitSlop = new PhraseQuery();
|
||||
expectedWithMultiDigitSlop.add(new Term("field", "foo"));
|
||||
expectedWithMultiDigitSlop.add(new Term("field", "bar"));
|
||||
expectedWithMultiDigitSlop.setSlop(10);
|
||||
PhraseQuery expectedWithMultiDigitSlop = new PhraseQuery(10, "field", "foo", "bar");
|
||||
|
||||
assertEquals(expectedWithMultiDigitSlop, parse("\"foo bar\"~10"));
|
||||
|
||||
PhraseQuery expectedNoSlop = new PhraseQuery();
|
||||
expectedNoSlop.add(new Term("field", "foo"));
|
||||
expectedNoSlop.add(new Term("field", "bar"));
|
||||
PhraseQuery expectedNoSlop = new PhraseQuery("field", "foo", "bar");
|
||||
|
||||
assertEquals("Ignore trailing tilde with no slop", expectedNoSlop, parse("\"foo bar\"~"));
|
||||
assertEquals("Ignore non-numeric trailing slop", expectedNoSlop, parse("\"foo bar\"~a"));
|
||||
assertEquals("Ignore non-numeric trailing slop", expectedNoSlop, parse("\"foo bar\"~1a"));
|
||||
assertEquals("Ignore negative trailing slop", expectedNoSlop, parse("\"foo bar\"~-1"));
|
||||
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("field", "foo"));
|
||||
pq.add(new Term("field", "bar"));
|
||||
pq.setSlop(12);
|
||||
PhraseQuery pq = new PhraseQuery(12, "field", "foo", "bar");
|
||||
|
||||
BooleanQuery expectedBoolean = new BooleanQuery();
|
||||
expectedBoolean.add(pq, Occur.MUST);
|
||||
|
@ -165,12 +152,8 @@ public class TestSimpleQueryParser extends LuceneTestCase {
|
|||
|
||||
/** test some AND'd phrases using '+' operator */
|
||||
public void testANDPhrase() throws Exception {
|
||||
PhraseQuery phrase1 = new PhraseQuery();
|
||||
phrase1.add(new Term("field", "foo"));
|
||||
phrase1.add(new Term("field", "bar"));
|
||||
PhraseQuery phrase2 = new PhraseQuery();
|
||||
phrase2.add(new Term("field", "star"));
|
||||
phrase2.add(new Term("field", "wars"));
|
||||
PhraseQuery phrase1 = new PhraseQuery("field", "foo", "bar");
|
||||
PhraseQuery phrase2 = new PhraseQuery("field", "star", "wars");
|
||||
BooleanQuery expected = new BooleanQuery();
|
||||
expected.add(phrase1, Occur.MUST);
|
||||
expected.add(phrase2, Occur.MUST);
|
||||
|
@ -209,12 +192,8 @@ public class TestSimpleQueryParser extends LuceneTestCase {
|
|||
|
||||
/** test some OR'd phrases using '|' operator */
|
||||
public void testORPhrase() throws Exception {
|
||||
PhraseQuery phrase1 = new PhraseQuery();
|
||||
phrase1.add(new Term("field", "foo"));
|
||||
phrase1.add(new Term("field", "bar"));
|
||||
PhraseQuery phrase2 = new PhraseQuery();
|
||||
phrase2.add(new Term("field", "star"));
|
||||
phrase2.add(new Term("field", "wars"));
|
||||
PhraseQuery phrase1 = new PhraseQuery("field", "foo", "bar");
|
||||
PhraseQuery phrase2 = new PhraseQuery("field", "star", "wars");
|
||||
BooleanQuery expected = new BooleanQuery();
|
||||
expected.add(phrase1, Occur.SHOULD);
|
||||
expected.add(phrase2, Occur.SHOULD);
|
||||
|
@ -324,9 +303,7 @@ public class TestSimpleQueryParser extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testGarbagePhrase() throws Exception {
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
expected.add(new Term("field", "star"));
|
||||
expected.add(new Term("field", "wars"));
|
||||
PhraseQuery expected = new PhraseQuery("field", "star", "wars");
|
||||
|
||||
assertEquals(expected, parse("\"star wars\""));
|
||||
assertEquals(expected, parse("\"star wars\\ \""));
|
||||
|
@ -614,9 +591,7 @@ public class TestSimpleQueryParser extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public void testDisableSlop() {
|
||||
PhraseQuery expectedPhrase = new PhraseQuery();
|
||||
expectedPhrase.add(new Term("field", "foo"));
|
||||
expectedPhrase.add(new Term("field", "bar"));
|
||||
PhraseQuery expectedPhrase = new PhraseQuery("field", "foo", "bar");
|
||||
|
||||
BooleanQuery expected = new BooleanQuery();
|
||||
expected.add(expectedPhrase, Occur.MUST);
|
||||
|
|
|
@ -298,9 +298,7 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
|
|||
// individual CJK chars as terms
|
||||
SimpleCJKAnalyzer analyzer = new SimpleCJKAnalyzer();
|
||||
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
expected.add(new Term("field", "中"));
|
||||
expected.add(new Term("field", "国"));
|
||||
PhraseQuery expected = new PhraseQuery("field", "中", "国");
|
||||
|
||||
assertEquals(expected, getQuery("\"中国\"", analyzer));
|
||||
}
|
||||
|
@ -309,10 +307,8 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
|
|||
// individual CJK chars as terms
|
||||
SimpleCJKAnalyzer analyzer = new SimpleCJKAnalyzer();
|
||||
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
PhraseQuery expected = new PhraseQuery("field", "中", "国");
|
||||
expected.setBoost(0.5f);
|
||||
expected.add(new Term("field", "中"));
|
||||
expected.add(new Term("field", "国"));
|
||||
|
||||
assertEquals(expected, getQuery("\"中国\"^0.5", analyzer));
|
||||
}
|
||||
|
@ -321,10 +317,7 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
|
|||
// individual CJK chars as terms
|
||||
SimpleCJKAnalyzer analyzer = new SimpleCJKAnalyzer();
|
||||
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
expected.setSlop(3);
|
||||
expected.add(new Term("field", "中"));
|
||||
expected.add(new Term("field", "国"));
|
||||
PhraseQuery expected = new PhraseQuery(3, "field", "中", "国");
|
||||
|
||||
assertEquals(expected, getQuery("\"中国\"~3", analyzer));
|
||||
}
|
||||
|
@ -333,9 +326,7 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
|
|||
// individual CJK chars as terms
|
||||
SimpleCJKAnalyzer analyzer = new SimpleCJKAnalyzer();
|
||||
|
||||
PhraseQuery expected = new PhraseQuery();
|
||||
expected.add(new Term("field", "中"));
|
||||
expected.add(new Term("field", "国"));
|
||||
PhraseQuery expected = new PhraseQuery("field", "中", "国");
|
||||
CommonQueryParserConfiguration qp = getParserConfig(analyzer);
|
||||
setAutoGeneratePhraseQueries(qp, true);
|
||||
assertEquals(expected, getQuery("中国",qp));
|
||||
|
@ -1259,10 +1250,10 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
|
|||
new MockAnalyzer(random(), MockTokenizer.WHITESPACE, false, stopStopList));
|
||||
qp.setEnablePositionIncrements(true);
|
||||
|
||||
PhraseQuery phraseQuery = new PhraseQuery();
|
||||
PhraseQuery.Builder phraseQuery = new PhraseQuery.Builder();
|
||||
phraseQuery.add(new Term("field", "1"));
|
||||
phraseQuery.add(new Term("field", "2"), 2);
|
||||
assertEquals(phraseQuery, getQuery("\"1 stop 2\"",qp));
|
||||
assertEquals(phraseQuery.build(), getQuery("\"1 stop 2\"",qp));
|
||||
}
|
||||
|
||||
public void testMatchAllQueryParsing() throws Exception {
|
||||
|
|
|
@ -673,9 +673,7 @@ public abstract class ThreadedIndexingAndSearchingTestCase extends LuceneTestCas
|
|||
protected void smokeTestSearcher(IndexSearcher s) throws Exception {
|
||||
runQuery(s, new TermQuery(new Term("body", "united")));
|
||||
runQuery(s, new TermQuery(new Term("titleTokenized", "states")));
|
||||
PhraseQuery pq = new PhraseQuery();
|
||||
pq.add(new Term("body", "united"));
|
||||
pq.add(new Term("body", "states"));
|
||||
PhraseQuery pq = new PhraseQuery("body", "united", "states");
|
||||
runQuery(s, pq);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,10 +151,7 @@ public abstract class SearchEquivalenceTestBase extends LuceneTestCase {
|
|||
query = TermRangeQuery.newStringRange("field", "a", "" + randomChar(), true, true);
|
||||
} else {
|
||||
// use a query with a two-phase approximation
|
||||
PhraseQuery phrase = new PhraseQuery();
|
||||
phrase.add(new Term("field", "" + randomChar()));
|
||||
phrase.add(new Term("field", "" + randomChar()));
|
||||
phrase.setSlop(100);
|
||||
PhraseQuery phrase = new PhraseQuery(100, "field", "" + randomChar(), "" + randomChar());
|
||||
query = phrase;
|
||||
}
|
||||
|
||||
|
|
|
@ -387,7 +387,16 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
|
|||
if (subQParser == null) {
|
||||
|
||||
if (query instanceof PhraseQuery) {
|
||||
((PhraseQuery) query).setSlop(slop);
|
||||
PhraseQuery pq = (PhraseQuery) query;
|
||||
Term[] terms = pq.getTerms();
|
||||
int[] positions = pq.getPositions();
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
for (int i = 0; i < terms.length; ++i) {
|
||||
builder.add(terms[i], positions[i]);
|
||||
}
|
||||
builder.setSlop(slop);
|
||||
query = builder.build();
|
||||
query.setBoost(pq.getBoost());
|
||||
}
|
||||
if (query instanceof MultiPhraseQuery) {
|
||||
((MultiPhraseQuery) query).setSlop(slop);
|
||||
|
|
|
@ -17,12 +17,22 @@
|
|||
|
||||
package org.apache.solr.search;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.core.StopFilterFactory;
|
||||
import org.apache.lucene.analysis.util.TokenFilterFactory;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.queries.function.BoostedQuery;
|
||||
import org.apache.lucene.queries.function.FunctionQuery;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
|
@ -45,17 +55,9 @@ import org.apache.solr.request.SolrQueryRequest;
|
|||
import org.apache.solr.schema.FieldType;
|
||||
import org.apache.solr.util.SolrPluginUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
|
||||
/**
|
||||
* Query parser that generates DisjunctionMaxQueries based on user configuration.
|
||||
|
@ -1240,7 +1242,14 @@ public class ExtendedDismaxQParser extends QParser {
|
|||
if (query instanceof PhraseQuery) {
|
||||
PhraseQuery pq = (PhraseQuery)query;
|
||||
if (minClauseSize > 1 && pq.getTerms().length < minClauseSize) return null;
|
||||
((PhraseQuery)query).setSlop(slop);
|
||||
PhraseQuery.Builder builder = new PhraseQuery.Builder();
|
||||
Term[] terms = pq.getTerms();
|
||||
int[] positions = pq.getPositions();
|
||||
for (int i = 0; i < terms.length; ++i) {
|
||||
builder.add(terms[i], positions[i]);
|
||||
}
|
||||
builder.setSlop(slop);
|
||||
query = builder.build();
|
||||
} else if (query instanceof MultiPhraseQuery) {
|
||||
MultiPhraseQuery pq = (MultiPhraseQuery)query;
|
||||
if (minClauseSize > 1 && pq.getTermArrays().size() < minClauseSize) return null;
|
||||
|
|
Loading…
Reference in New Issue