You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2010/11/15 00:13:47 UTC
svn commit: r1035096 [2/2] - in /lucene/dev/trunk/lucene: ./ contrib/
contrib/queries/src/java/org/apache/lucene/search/
contrib/queries/src/java/org/apache/lucene/search/regex/
contrib/queries/src/test/org/apache/lucene/search/regex/ contrib/spellchec...
Added: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java?rev=1035096&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java (added)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java Sun Nov 14 23:13:46 2010
@@ -0,0 +1,182 @@
+package org.apache.lucene.search;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.Comparator;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.util.ArrayUtil;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * Base rewrite method for collecting only the top terms
+ * via a priority queue.
+ * @lucene.internal Only public to be accessible by spans package.
+ */
+public abstract class TopTermsRewrite<Q extends Query> extends TermCollectingRewrite<Q> {
+
+ private final int size;
+
+ /**
+ * Create a TopTermsBooleanQueryRewrite for
+ * at most <code>size</code> terms.
+ * <p>
+ * NOTE: if {@link BooleanQuery#getMaxClauseCount} is smaller than
+ * <code>size</code>, then it will be used instead.
+ */
+ public TopTermsRewrite(int size) {
+ this.size = size;
+ }
+
+ /** return the maximum priority queue size */
+ public int getSize() {
+ return size;
+ }
+
+ /** return the maximum size of the priority queue (for boolean rewrites this is BooleanQuery#getMaxClauseCount). */
+ protected abstract int getMaxSize();
+
+ @Override
+ public final Q rewrite(final IndexReader reader, final MultiTermQuery query) throws IOException {
+ final int maxSize = Math.min(size, getMaxSize());
+ final PriorityQueue<ScoreTerm> stQueue = new PriorityQueue<ScoreTerm>();
+ collectTerms(reader, query, new TermCollector() {
+ private final MaxNonCompetitiveBoostAttribute maxBoostAtt =
+ attributes.addAttribute(MaxNonCompetitiveBoostAttribute.class);
+
+ private final Map<BytesRef,ScoreTerm> visitedTerms = new HashMap<BytesRef,ScoreTerm>();
+
+ private TermsEnum termsEnum;
+ private Comparator<BytesRef> termComp;
+ private BoostAttribute boostAtt;
+ private ScoreTerm st;
+
+ @Override
+ public void setNextEnum(TermsEnum termsEnum) throws IOException {
+ this.termsEnum = termsEnum;
+ this.termComp = termsEnum.getComparator();
+ // lazy init the initial ScoreTerm because comparator is not known on ctor:
+ if (st == null)
+ st = new ScoreTerm(this.termComp);
+ boostAtt = termsEnum.attributes().addAttribute(BoostAttribute.class);
+ }
+
+ @Override
+ public boolean collect(BytesRef bytes) {
+ final float boost = boostAtt.getBoost();
+ // ignore uncompetetive hits
+ if (stQueue.size() == maxSize) {
+ final ScoreTerm t = stQueue.peek();
+ if (boost < t.boost)
+ return true;
+ if (boost == t.boost && termComp.compare(bytes, t.bytes) > 0)
+ return true;
+ }
+ ScoreTerm t = visitedTerms.get(bytes);
+ if (t != null) {
+ // if the term is already in the PQ, only update docFreq of term in PQ
+ t.docFreq += termsEnum.docFreq();
+ assert t.boost == boost : "boost should be equal in all segment TermsEnums";
+ } else {
+ // add new entry in PQ, we must clone the term, else it may get overwritten!
+ st.bytes.copy(bytes);
+ st.boost = boost;
+ st.docFreq = termsEnum.docFreq();
+ visitedTerms.put(st.bytes, st);
+ stQueue.offer(st);
+ // possibly drop entries from queue
+ if (stQueue.size() > maxSize) {
+ st = stQueue.poll();
+ visitedTerms.remove(st.bytes);
+ } else {
+ st = new ScoreTerm(termComp);
+ }
+ assert stQueue.size() <= maxSize : "the PQ size must be limited to maxSize";
+ // set maxBoostAtt with values to help FuzzyTermsEnum to optimize
+ if (stQueue.size() == maxSize) {
+ t = stQueue.peek();
+ maxBoostAtt.setMaxNonCompetitiveBoost(t.boost);
+ maxBoostAtt.setCompetitiveTerm(t.bytes);
+ }
+ }
+ return true;
+ }
+ });
+
+ final Term placeholderTerm = new Term(query.field);
+ final Q q = getTopLevelQuery();
+ final ScoreTerm[] scoreTerms = stQueue.toArray(new ScoreTerm[stQueue.size()]);
+ ArrayUtil.quickSort(scoreTerms, scoreTermSortByTermComp);
+ for (final ScoreTerm st : scoreTerms) {
+ final Term term = placeholderTerm.createTerm(st.bytes);
+ assert reader.docFreq(term) == st.docFreq;
+ addClause(q, term, st.docFreq, query.getBoost() * st.boost); // add to query
+ }
+ query.incTotalNumberOfTerms(scoreTerms.length);
+ return q;
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * size;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ final TopTermsRewrite other = (TopTermsRewrite) obj;
+ if (size != other.size) return false;
+ return true;
+ }
+
+ private static final Comparator<ScoreTerm> scoreTermSortByTermComp =
+ new Comparator<ScoreTerm>() {
+ public int compare(ScoreTerm st1, ScoreTerm st2) {
+ assert st1.termComp == st2.termComp :
+ "term comparator should not change between segments";
+ return st1.termComp.compare(st1.bytes, st2.bytes);
+ }
+ };
+
+ static final class ScoreTerm implements Comparable<ScoreTerm> {
+ public final Comparator<BytesRef> termComp;
+
+ public final BytesRef bytes = new BytesRef();
+ public float boost;
+ public int docFreq;
+
+ public ScoreTerm(Comparator<BytesRef> termComp) {
+ this.termComp = termComp;
+ }
+
+ public int compareTo(ScoreTerm other) {
+ if (this.boost == other.boost)
+ return termComp.compare(other.bytes, this.bytes);
+ else
+ return Float.compare(this.boost, other.boost);
+ }
+ }
+}
Propchange: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java?rev=1035096&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java (added)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java Sun Nov 14 23:13:46 2010
@@ -0,0 +1,234 @@
+package org.apache.lucene.search.spans;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.MultiTermQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TopTermsRewrite;
+import org.apache.lucene.search.ScoringRewrite;
+import org.apache.lucene.search.BooleanClause.Occur; // javadocs only
+
+/**
+ * Wraps any {@link MultiTermQuery} as a {@link SpanQuery},
+ * so it can be nested within other SpanQuery classes.
+ * <p>
+ * The query is rewritten by default to a {@link SpanOrQuery} containing
+ * the expanded terms, but this can be customized.
+ * <p>
+ * Example:
+ * <blockquote><pre>
+ * {@code
+ * WildcardQuery wildcard = new WildcardQuery(new Term("field", "bro?n"));
+ * SpanQuery spanWildcard = new SpanMultiTermQueryWrapper<WildcardQuery>(wildcard);
+ * // do something with spanWildcard, such as use it in a SpanFirstQuery
+ * }
+ * </pre></blockquote>
+ */
+public class SpanMultiTermQueryWrapper<Q extends MultiTermQuery> extends SpanQuery {
+ protected final Q query;
+
+ /**
+ * Create a new SpanMultiTermQueryWrapper.
+ *
+ * @param query Query to wrap.
+ * <p>
+ * NOTE: This will call {@link MultiTermQuery#setRewriteMethod(MultiTermQuery.RewriteMethod)}
+ * on the wrapped <code>query</code>, changing its rewrite method to a suitable one for spans.
+ * Be sure to not change the rewrite method on the wrapped query afterwards! Doing so will
+ * throw {@link UnsupportedOperationException} on rewriting this query!
+ */
+ public SpanMultiTermQueryWrapper(Q query) {
+ this.query = query;
+
+ MultiTermQuery.RewriteMethod method = query.getRewriteMethod();
+ if (method instanceof TopTermsRewrite) {
+ final int pqsize = ((TopTermsRewrite) method).getSize();
+ setRewriteMethod(new TopTermsSpanBooleanQueryRewrite(pqsize));
+ } else {
+ setRewriteMethod(SCORING_SPAN_QUERY_REWRITE);
+ }
+ }
+
+ /**
+ * Expert: returns the rewriteMethod
+ */
+ public final SpanRewriteMethod getRewriteMethod() {
+ final MultiTermQuery.RewriteMethod m = query.getRewriteMethod();
+ if (!(m instanceof SpanRewriteMethod))
+ throw new UnsupportedOperationException("You can only use SpanMultiTermQueryWrapper with a suitable SpanRewriteMethod.");
+ return (SpanRewriteMethod) m;
+ }
+
+ /**
+ * Expert: sets the rewrite method. This only makes sense
+ * to be a span rewrite method.
+ */
+ public final void setRewriteMethod(SpanRewriteMethod rewriteMethod) {
+ query.setRewriteMethod(rewriteMethod);
+ }
+
+ @Override
+ public Spans getSpans(IndexReader reader) throws IOException {
+ throw new UnsupportedOperationException("Query should have been rewritten");
+ }
+
+ @Override
+ public String getField() {
+ return query.getField();
+ }
+
+ @Override
+ public String toString(String field) {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SpanMultiTermQueryWrapper(");
+ builder.append(query.toString(field));
+ builder.append(")");
+ return builder.toString();
+ }
+
+ @Override
+ public Query rewrite(IndexReader reader) throws IOException {
+ final Query q = query.rewrite(reader);
+ if (!(q instanceof SpanQuery))
+ throw new UnsupportedOperationException("You can only use SpanMultiTermQueryWrapper with a suitable SpanRewriteMethod.");
+ return q;
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * query.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ final SpanMultiTermQueryWrapper other = (SpanMultiTermQueryWrapper) obj;
+ return query.equals(other.query);
+ }
+
+ /** Abstract class that defines how the query is rewritten. */
+ public static abstract class SpanRewriteMethod extends MultiTermQuery.RewriteMethod {
+ @Override
+ public abstract SpanQuery rewrite(IndexReader reader, MultiTermQuery query) throws IOException;
+ }
+
+ /**
+ * A rewrite method that first translates each term into a SpanTermQuery in a
+ * {@link Occur#SHOULD} clause in a BooleanQuery, and keeps the
+ * scores as computed by the query.
+ *
+ * @see #setRewriteMethod
+ */
+ public final static SpanRewriteMethod SCORING_SPAN_QUERY_REWRITE = new SpanRewriteMethod() {
+ private final ScoringRewrite<SpanOrQuery> delegate = new ScoringRewrite<SpanOrQuery>() {
+ @Override
+ protected SpanOrQuery getTopLevelQuery() {
+ return new SpanOrQuery();
+ }
+
+ @Override
+ protected void addClause(SpanOrQuery topLevel, Term term, int docCount, float boost) {
+ final SpanTermQuery q = new SpanTermQuery(term);
+ q.setBoost(boost);
+ topLevel.addClause(q);
+ }
+ };
+
+ @Override
+ public SpanQuery rewrite(IndexReader reader, MultiTermQuery query) throws IOException {
+ return delegate.rewrite(reader, query);
+ }
+
+ // Make sure we are still a singleton even after deserializing
+ protected Object readResolve() {
+ return SCORING_SPAN_QUERY_REWRITE;
+ }
+ };
+
+ /**
+ * A rewrite method that first translates each term into a SpanTermQuery in a
+ * {@link Occur#SHOULD} clause in a BooleanQuery, and keeps the
+ * scores as computed by the query.
+ *
+ * <p>
+ * This rewrite method only uses the top scoring terms so it will not overflow
+ * the boolean max clause count.
+ *
+ * @see #setRewriteMethod
+ */
+ public static final class TopTermsSpanBooleanQueryRewrite extends SpanRewriteMethod {
+ private final TopTermsRewrite<SpanOrQuery> delegate;
+
+ /**
+ * Create a TopTermsSpanBooleanQueryRewrite for
+ * at most <code>size</code> terms.
+ */
+ public TopTermsSpanBooleanQueryRewrite(int size) {
+ delegate = new TopTermsRewrite<SpanOrQuery>(size) {
+ @Override
+ protected int getMaxSize() {
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
+ protected SpanOrQuery getTopLevelQuery() {
+ return new SpanOrQuery();
+ }
+
+ @Override
+ protected void addClause(SpanOrQuery topLevel, Term term, int docFreq, float boost) {
+ final SpanTermQuery q = new SpanTermQuery(term);
+ q.setBoost(boost);
+ topLevel.addClause(q);
+ }
+ };
+ }
+
+ /** return the maximum priority queue size */
+ public int getSize() {
+ return delegate.getSize();
+ }
+
+ @Override
+ public SpanQuery rewrite(IndexReader reader, MultiTermQuery query) throws IOException {
+ return delegate.rewrite(reader, query);
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * delegate.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ final TopTermsSpanBooleanQueryRewrite other = (TopTermsSpanBooleanQueryRewrite) obj;
+ return delegate.equals(other.delegate);
+ }
+
+ }
+
+}
Propchange: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanOrQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanOrQuery.java?rev=1035096&r1=1035095&r2=1035096&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanOrQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanOrQuery.java Sun Nov 14 23:13:46 2010
@@ -42,16 +42,20 @@ public class SpanOrQuery extends SpanQue
// copy clauses array into an ArrayList
this.clauses = new ArrayList<SpanQuery>(clauses.length);
for (int i = 0; i < clauses.length; i++) {
- SpanQuery clause = clauses[i];
- if (i == 0) { // check field
- field = clause.getField();
- } else if (!clause.getField().equals(field)) {
- throw new IllegalArgumentException("Clauses must have same field.");
- }
- this.clauses.add(clause);
+ addClause(clauses[i]);
}
}
+ /** Adds a clause to this query */
+ public final void addClause(SpanQuery clause) {
+ if (field == null) {
+ field = clause.getField();
+ } else if (!clause.getField().equals(field)) {
+ throw new IllegalArgumentException("Clauses must have same field.");
+ }
+ this.clauses.add(clause);
+ }
+
/** Return the clauses whose spans are matched. */
public SpanQuery[] getClauses() {
return clauses.toArray(new SpanQuery[clauses.size()]);
Modified: lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java?rev=1035096&r1=1035095&r2=1035096&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java (original)
+++ lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java Sun Nov 14 23:13:46 2010
@@ -147,8 +147,8 @@ public class TestMultiTermQueryRewrites
@Override
protected TermsEnum getTermsEnum(IndexReader reader, AttributeSource atts) throws IOException {
return new TermRangeTermsEnum(reader, field, "2", "7", true, true, null) {
- final MultiTermQuery.BoostAttribute boostAtt =
- attributes().addAttribute(MultiTermQuery.BoostAttribute.class);
+ final BoostAttribute boostAtt =
+ attributes().addAttribute(BoostAttribute.class);
@Override
protected AcceptStatus accept(BytesRef term) {
Added: lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java?rev=1035096&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java (added)
+++ lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java Sun Nov 14 23:13:46 2010
@@ -0,0 +1,92 @@
+package org.apache.lucene.search.spans;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.FuzzyQuery;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.WildcardQuery;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.LuceneTestCase;
+
+/**
+ * Tests for {@link SpanMultiTermQueryWrapper}, wrapping a few MultiTermQueries.
+ */
+public class TestSpanMultiTermQueryWrapper extends LuceneTestCase {
+ private Directory directory;
+ private IndexReader reader;
+ private Searcher searcher;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ directory = newDirectory();
+ RandomIndexWriter iw = new RandomIndexWriter(random, directory);
+ Document doc = new Document();
+ Field field = newField("field", "", Field.Store.NO, Field.Index.ANALYZED);
+ doc.add(field);
+
+ field.setValue("quick brown fox");
+ iw.addDocument(doc);
+ field.setValue("jumps over lazy broun dog");
+ iw.addDocument(doc);
+ field.setValue("jumps over extremely very lazy broxn dog");
+ iw.addDocument(doc);
+ reader = iw.getReader();
+ iw.close();
+ searcher = new IndexSearcher(reader);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ searcher.close();
+ reader.close();
+ directory.close();
+ super.tearDown();
+ }
+
+ public void testWildcard() throws Exception {
+ WildcardQuery wq = new WildcardQuery(new Term("field", "bro?n"));
+ SpanQuery swq = new SpanMultiTermQueryWrapper<WildcardQuery>(wq);
+ // will only match quick brown fox
+ SpanFirstQuery sfq = new SpanFirstQuery(swq, 2);
+ assertEquals(1, searcher.search(sfq, 10).totalHits);
+ }
+
+ public void testFuzzy() throws Exception {
+ FuzzyQuery fq = new FuzzyQuery(new Term("field", "broan"));
+ SpanQuery sfq = new SpanMultiTermQueryWrapper<FuzzyQuery>(fq);
+ // will not match quick brown fox
+ SpanPositionRangeQuery sprq = new SpanPositionRangeQuery(sfq, 3, 6);
+ assertEquals(2, searcher.search(sprq, 10).totalHits);
+ }
+
+ public void testFuzzy2() throws Exception {
+ // maximum of 1 term expansion
+ FuzzyQuery fq = new FuzzyQuery(new Term("field", "broan"), 1f, 0, 1);
+ SpanQuery sfq = new SpanMultiTermQueryWrapper<FuzzyQuery>(fq);
+ // will only match jumps over lazy broun dog
+ SpanPositionRangeQuery sprq = new SpanPositionRangeQuery(sfq, 0, 100);
+ assertEquals(1, searcher.search(sprq, 10).totalHits);
+ }
+}
Propchange: lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL