You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ro...@apache.org on 2014/11/12 15:56:24 UTC
svn commit: r1638805 [4/8] - in /lucene/dev/lucene2878:
dev-tools/idea/lucene/highlighter/
lucene/analysis/common/src/test/org/apache/lucene/analysis/sinks/
lucene/analysis/common/src/test/org/apache/lucene/analysis/standard/
lucene/codecs/src/java/org...
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TermQuery.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TermQuery.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TermQuery.java Wed Nov 12 14:56:17 2014
@@ -17,71 +17,75 @@ package org.apache.lucene.search;
* limitations under the License.
*/
-import java.io.IOException;
-import java.util.Set;
-
-import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.DocsEnum;
-import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.IndexReaderContext;
+import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.ReaderUtil;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext;
import org.apache.lucene.index.TermState;
import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
import org.apache.lucene.search.similarities.Similarity;
+import org.apache.lucene.search.similarities.Similarity.SimScorer;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.ToStringUtils;
-/** A Query that matches documents containing a term.
- This may be combined with other terms with a {@link BooleanQuery}.
- */
+import java.io.IOException;
+import java.util.Set;
+
+/**
+ * A Query that matches documents containing a term. This may be combined with
+ * other terms with a {@link BooleanQuery}.
+ */
public class TermQuery extends Query {
private final Term term;
private final int docFreq;
private final TermContext perReaderTermState;
-
+
final class TermWeight extends Weight {
private final Similarity similarity;
private final Similarity.SimWeight stats;
private final TermContext termStates;
-
+
public TermWeight(IndexSearcher searcher, TermContext termStates)
- throws IOException {
+ throws IOException {
assert termStates != null : "TermContext must not be null";
this.termStates = termStates;
this.similarity = searcher.getSimilarity();
- this.stats = similarity.computeWeight(
- getBoost(),
- searcher.collectionStatistics(term.field()),
+ this.stats = similarity.computeWeight(getBoost(),
+ searcher.collectionStatistics(term.field()),
searcher.termStatistics(term, termStates));
}
-
+
@Override
- public String toString() { return "weight(" + TermQuery.this + ")"; }
-
+ public String toString() {
+ return "weight(" + TermQuery.this + ")";
+ }
+
@Override
- public Query getQuery() { return TermQuery.this; }
-
+ public Query getQuery() {
+ return TermQuery.this;
+ }
+
@Override
public float getValueForNormalization() {
return stats.getValueForNormalization();
}
-
+
@Override
public void normalize(float queryNorm, float topLevelBoost) {
stats.normalize(queryNorm, topLevelBoost);
}
-
+
@Override
- public Scorer scorer(LeafReaderContext context, Bits acceptDocs) throws IOException {
+ public Scorer scorer(LeafReaderContext context, int flags, Bits acceptDocs) throws IOException {
assert termStates.topReaderContext == ReaderUtil.getTopLevelContext(context) : "The top-reader used to create Weight (" + termStates.topReaderContext + ") is not the same as the current reader's top-reader (" + ReaderUtil.getTopLevelContext(context);
final TermsEnum termsEnum = getTermsEnum(context);
if (termsEnum == null) {
return null;
}
- DocsEnum docs = termsEnum.docs(acceptDocs, null);
+ DocsEnum docs = termsEnum.docs(acceptDocs, null, flags);
assert docs != null;
return new TermScorer(this, docs, similarity.simScorer(stats, context));
}
@@ -96,90 +100,100 @@ public class TermQuery extends Query {
assert termNotInReader(context.reader(), term) : "no termstate found but term exists in reader term=" + term;
return null;
}
- //System.out.println("LD=" + reader.getLiveDocs() + " set?=" + (reader.getLiveDocs() != null ? reader.getLiveDocs().get(0) : "null"));
- final TermsEnum termsEnum = context.reader().terms(term.field()).iterator(null);
+ // System.out.println("LD=" + reader.getLiveDocs() + " set?=" +
+ // (reader.getLiveDocs() != null ? reader.getLiveDocs().get(0) : "null"));
+ final TermsEnum termsEnum = context.reader().terms(term.field())
+ .iterator(null);
termsEnum.seekExact(term.bytes(), state);
return termsEnum;
}
private boolean termNotInReader(LeafReader reader, Term term) throws IOException {
// only called from assert
- //System.out.println("TQ.termNotInReader reader=" + reader + " term=" + field + ":" + bytes.utf8ToString());
+ // System.out.println("TQ.termNotInReader reader=" + reader + " term=" +
+ // field + ":" + bytes.utf8ToString());
return reader.docFreq(term) == 0;
}
@Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
- Scorer scorer = scorer(context, context.reader().getLiveDocs());
+ Scorer scorer = scorer(context, DocsEnum.FLAG_FREQS, context.reader().getLiveDocs());
if (scorer != null) {
int newDoc = scorer.advance(doc);
if (newDoc == doc) {
float freq = scorer.freq();
SimScorer docScorer = similarity.simScorer(stats, context);
ComplexExplanation result = new ComplexExplanation();
- result.setDescription("weight("+getQuery()+" in "+doc+") [" + similarity.getClass().getSimpleName() + "], result of:");
- Explanation scoreExplanation = docScorer.explain(doc, new Explanation(freq, "termFreq=" + freq));
+ result.setDescription("weight(" + getQuery() + " in " + doc + ") ["
+ + similarity.getClass().getSimpleName() + "], result of:");
+ Explanation scoreExplanation = docScorer.explain(doc,
+ new Explanation(freq, "termFreq=" + freq));
result.addDetail(scoreExplanation);
result.setValue(scoreExplanation.getValue());
result.setMatch(true);
return result;
}
}
- return new ComplexExplanation(false, 0.0f, "no matching term");
+ return new ComplexExplanation(false, 0.0f, "no matching term");
}
}
-
+
/** Constructs a query for the term <code>t</code>. */
public TermQuery(Term t) {
this(t, -1);
}
-
- /** Expert: constructs a TermQuery that will use the
- * provided docFreq instead of looking up the docFreq
- * against the searcher. */
+
+ /**
+ * Expert: constructs a TermQuery that will use the provided docFreq instead
+ * of looking up the docFreq against the searcher.
+ */
public TermQuery(Term t, int docFreq) {
term = t;
this.docFreq = docFreq;
perReaderTermState = null;
}
- /** Expert: constructs a TermQuery that will use the
- * provided docFreq instead of looking up the docFreq
- * against the searcher. */
+ /**
+ * Expert: constructs a TermQuery that will use the provided docFreq instead
+ * of looking up the docFreq against the searcher.
+ */
public TermQuery(Term t, TermContext states) {
assert states != null;
term = t;
docFreq = states.docFreq();
perReaderTermState = states;
}
-
+
/** Returns the term of this query. */
- public Term getTerm() { return term; }
-
+ public Term getTerm() {
+ return term;
+ }
+
@Override
public Weight createWeight(IndexSearcher searcher) throws IOException {
final IndexReaderContext context = searcher.getTopReaderContext();
final TermContext termState;
- if (perReaderTermState == null || perReaderTermState.topReaderContext != context) {
- // make TermQuery single-pass if we don't have a PRTS or if the context differs!
+ if (perReaderTermState == null
+ || perReaderTermState.topReaderContext != context) {
+ // make TermQuery single-pass if we don't have a PRTS or if the context
+ // differs!
termState = TermContext.build(context, term);
} else {
- // PRTS was pre-build for this IS
- termState = this.perReaderTermState;
+ // PRTS was pre-build for this IS
+ termState = this.perReaderTermState;
}
-
+
// we must not ignore the given docFreq - if set use the given value (lie)
- if (docFreq != -1)
- termState.setDocFreq(docFreq);
+ if (docFreq != -1) termState.setDocFreq(docFreq);
return new TermWeight(searcher, termState);
}
-
+
@Override
public void extractTerms(Set<Term> terms) {
terms.add(getTerm());
}
-
+
/** Prints a user-readable version of this query. */
@Override
public String toString(String field) {
@@ -192,21 +206,20 @@ public class TermQuery extends Query {
buffer.append(ToStringUtils.boost(getBoost()));
return buffer.toString();
}
-
+
/** Returns true iff <code>o</code> is equal to this. */
@Override
public boolean equals(Object o) {
- if (!(o instanceof TermQuery))
- return false;
- TermQuery other = (TermQuery)o;
+ if (!(o instanceof TermQuery)) return false;
+ TermQuery other = (TermQuery) o;
return (this.getBoost() == other.getBoost())
- && this.term.equals(other.term);
+ && this.term.equals(other.term);
}
-
- /** Returns a hash code value for this object.*/
+
+ /** Returns a hash code value for this object. */
@Override
public int hashCode() {
return Float.floatToIntBits(getBoost()) ^ term.hashCode();
}
-
+
}
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TermScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TermScorer.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TermScorer.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TermScorer.java Wed Nov 12 14:56:17 2014
@@ -17,10 +17,11 @@ package org.apache.lucene.search;
* limitations under the License.
*/
-import java.io.IOException;
-
import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.search.similarities.Similarity;
+import org.apache.lucene.util.BytesRef;
+
+import java.io.IOException;
/** Expert: A <code>Scorer</code> for documents matching a <code>Term</code>.
*/
@@ -64,6 +65,36 @@ final class TermScorer extends Scorer {
public int nextDoc() throws IOException {
return docsEnum.nextDoc();
}
+
+ @Override
+ public int nextPosition() throws IOException {
+ return docsEnum.nextPosition();
+ }
+
+ @Override
+ public int startPosition() throws IOException {
+ return docsEnum.startPosition();
+ }
+
+ @Override
+ public int endPosition() throws IOException {
+ return docsEnum.endPosition();
+ }
+
+ @Override
+ public int startOffset() throws IOException {
+ return docsEnum.startOffset();
+ }
+
+ @Override
+ public int endOffset() throws IOException {
+ return docsEnum.endOffset();
+ }
+
+ @Override
+ public BytesRef getPayload() throws IOException {
+ return docsEnum.getPayload();
+ }
@Override
public float score() throws IOException {
@@ -92,5 +123,16 @@ final class TermScorer extends Scorer {
/** Returns a string representation of this <code>TermScorer</code>. */
@Override
- public String toString() { return "scorer(" + weight + ")"; }
+ public String toString() {
+ return "scorer(" + weight + ")[" + super.toString() + "]";
+ }
+
+ // TODO: benchmark if the specialized conjunction really benefits
+ // from this, or if instead its from sorting by docFreq, or both
+
+ DocsEnum getDocsEnum() {
+ return docsEnum;
+ }
+
+
}
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TimeLimitingCollector.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TimeLimitingCollector.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TimeLimitingCollector.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TimeLimitingCollector.java Wed Nov 12 14:56:17 2014
@@ -156,7 +156,12 @@ public class TimeLimitingCollector imple
};
}
-
+
+ @Override
+ public int postingFeatures() {
+ return collector.postingFeatures();
+ }
+
/**
* This is so the same timer can be used with a multi-phase search process such as grouping.
* We don't want to create a new TimeLimitingCollector for each phase because that would
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TotalHitCountCollector.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TotalHitCountCollector.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TotalHitCountCollector.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/TotalHitCountCollector.java Wed Nov 12 14:56:17 2014
@@ -17,6 +17,7 @@ package org.apache.lucene.search;
* limitations under the License.
*/
+import org.apache.lucene.index.DocsEnum;
/**
* Just counts the total number of hits.
@@ -36,6 +37,12 @@ public class TotalHitCountCollector exte
}
@Override
+ public int postingFeatures() {
+ // we don't need frequencies here
+ return DocsEnum.FLAG_NONE;
+ }
+
+ @Override
public boolean acceptsDocsOutOfOrder() {
return true;
}
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/Weight.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/Weight.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/Weight.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/Weight.java Wed Nov 12 14:56:17 2014
@@ -17,13 +17,13 @@ package org.apache.lucene.search;
* limitations under the License.
*/
-import java.io.IOException;
-
+import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.IndexReaderContext; // javadocs
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.util.Bits;
+import java.io.IOException;
+
/**
* Expert: Calculate query weights and build query scorers.
* <p>
@@ -34,7 +34,7 @@ import org.apache.lucene.util.Bits;
* {@link org.apache.lucene.index.LeafReader} dependent state should reside in the {@link Scorer}.
* <p>
* Since {@link Weight} creates {@link Scorer} instances for a given
- * {@link org.apache.lucene.index.LeafReaderContext} ({@link #scorer(org.apache.lucene.index.LeafReaderContext, Bits)})
+ * {@link org.apache.lucene.index.LeafReaderContext} ({@link #scorer(org.apache.lucene.index.LeafReaderContext, int, Bits)})
* callers must maintain the relationship between the searcher's top-level
* {@link IndexReaderContext} and the context used to create a {@link Scorer}.
* <p>
@@ -49,7 +49,7 @@ import org.apache.lucene.util.Bits;
* <li>The query normalization factor is passed to {@link #normalize(float, float)}. At
* this point the weighting is complete.
* <li>A <code>Scorer</code> is constructed by
- * {@link #scorer(org.apache.lucene.index.LeafReaderContext, Bits)}.
+ * {@link #scorer(org.apache.lucene.index.LeafReaderContext, int, Bits)}.
* </ol>
*
* @since 2.9
@@ -96,7 +96,7 @@ public abstract class Weight {
* @return a {@link Scorer} which scores documents in/out-of order.
* @throws IOException if there is a low-level I/O error
*/
- public abstract Scorer scorer(LeafReaderContext context, Bits acceptDocs) throws IOException;
+ public abstract Scorer scorer(LeafReaderContext context, int flags, Bits acceptDocs) throws IOException;
/**
* Optional method, to return a {@link BulkScorer} to
@@ -125,9 +125,9 @@ public abstract class Weight {
* passes them to a collector.
* @throws IOException if there is a low-level I/O error
*/
- public BulkScorer bulkScorer(LeafReaderContext context, boolean scoreDocsInOrder, Bits acceptDocs) throws IOException {
+ public BulkScorer bulkScorer(LeafReaderContext context, boolean scoreDocsInOrder, int flags, Bits acceptDocs) throws IOException {
- Scorer scorer = scorer(context, acceptDocs);
+ Scorer scorer = scorer(context, flags, acceptDocs);
if (scorer == null) {
// No docs match
return null;
@@ -198,14 +198,13 @@ public abstract class Weight {
* Returns true iff this implementation scores docs only out of order. This
* method is used in conjunction with {@link Collector}'s
* {@link LeafCollector#acceptsDocsOutOfOrder() acceptsDocsOutOfOrder} and
- * {@link #bulkScorer(org.apache.lucene.index.LeafReaderContext, boolean, Bits)} to
+ * {@link #bulkScorer(org.apache.lucene.index.LeafReaderContext, boolean, int, Bits)} to
* create a matching {@link Scorer} instance for a given {@link Collector}, or
* vice versa.
* <p>
* <b>NOTE:</b> the default implementation returns <code>false</code>, i.e.
* the <code>Scorer</code> scores documents in-order.
*/
- public boolean scoresDocsOutOfOrder() {
- return false;
- }
+ public boolean scoresDocsOutOfOrder() { return false; }
+
}
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/package.html
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/package.html?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/package.html (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/package.html Wed Nov 12 14:56:17 2014
@@ -436,15 +436,15 @@ on the built-in available scoring models
that scores via a {@link org.apache.lucene.search.similarities.Similarity Similarity} will just defer to the Similarity's implementation:
{@link org.apache.lucene.search.similarities.Similarity.SimWeight#normalize SimWeight#normalize(float,float)}.</li>
<li>
- {@link org.apache.lucene.search.Weight#scorer(org.apache.lucene.index.LeafReaderContext, org.apache.lucene.util.Bits)
- scorer(LeafReaderContext context, Bits acceptDocs)} —
+ {@link org.apache.lucene.search.Weight#scorer(org.apache.lucene.index.LeafReaderContext, int, org.apache.lucene.util.Bits)
+ scorer(LeafReaderContext context, int flags, Bits acceptDocs)} —
Construct a new {@link org.apache.lucene.search.Scorer Scorer} for this Weight. See <a href="#scorerClass">The Scorer Class</a>
below for help defining a Scorer. As the name implies, the Scorer is responsible for doing the actual scoring of documents
given the Query.
</li>
<li>
- {@link org.apache.lucene.search.Weight#bulkScorer(org.apache.lucene.index.LeafReaderContext, boolean, org.apache.lucene.util.Bits)
- scorer(LeafReaderContext context, boolean scoreDocsInOrder, Bits acceptDocs)} —
+ {@link org.apache.lucene.search.Weight#bulkScorer(org.apache.lucene.index.LeafReaderContext, boolean, int, org.apache.lucene.util.Bits)
+ scorer(LeafReaderContext context, boolean scoreDocsInOrder, int flags, Bits acceptDocs)} —
Construct a new {@link org.apache.lucene.search.BulkScorer BulkScorer} for this Weight. See <a href="#bulkScorerClass">The BulkScorer Class</a>
below for help defining a BulkScorer. This is an optional method, and most queries do not implement it.
</li>
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java Wed Nov 12 14:56:17 2014
@@ -17,11 +17,12 @@ package org.apache.lucene.search.payload
* limitations under the License.
*/
+import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.ComplexExplanation;
import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
import org.apache.lucene.search.similarities.DefaultSimilarity;
import org.apache.lucene.search.similarities.Similarity;
@@ -148,14 +149,14 @@ public class PayloadNearQuery extends Sp
}
@Override
- public Scorer scorer(LeafReaderContext context, Bits acceptDocs) throws IOException {
+ public Scorer scorer(LeafReaderContext context, int flags, Bits acceptDocs) throws IOException {
return new PayloadNearSpanScorer(query.getSpans(context, acceptDocs, termContexts), this,
similarity, similarity.simScorer(stats, context));
}
@Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
- PayloadNearSpanScorer scorer = (PayloadNearSpanScorer) scorer(context, context.reader().getLiveDocs());
+ PayloadNearSpanScorer scorer = (PayloadNearSpanScorer) scorer(context, DocsEnum.FLAG_PAYLOADS, context.reader().getLiveDocs());
if (scorer != null) {
int newDoc = scorer.advance(doc);
if (newDoc == doc) {
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java Wed Nov 12 14:56:17 2014
@@ -19,7 +19,7 @@ package org.apache.lucene.search.payload
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
-import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -79,7 +79,7 @@ public class PayloadTermQuery extends Sp
}
@Override
- public Scorer scorer(LeafReaderContext context, Bits acceptDocs) throws IOException {
+ public Scorer scorer(LeafReaderContext context, int flags, Bits acceptDocs) throws IOException {
return new PayloadTermSpanScorer((TermSpans) query.getSpans(context, acceptDocs, termContexts),
this, similarity.simScorer(stats, context));
}
@@ -120,7 +120,7 @@ public class PayloadTermQuery extends Sp
protected void processPayload(Similarity similarity) throws IOException {
if (termSpans.isPayloadAvailable()) {
- final DocsAndPositionsEnum postings = termSpans.getPostings();
+ final DocsEnum postings = termSpans.getPostings();
payload = postings.getPayload();
if (payload != null) {
payloadScore = function.currentScore(doc, term.field(),
@@ -176,7 +176,7 @@ public class PayloadTermQuery extends Sp
@Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
- PayloadTermSpanScorer scorer = (PayloadTermSpanScorer) scorer(context, context.reader().getLiveDocs());
+ PayloadTermSpanScorer scorer = (PayloadTermSpanScorer) scorer(context, DocsEnum.FLAG_POSITIONS, context.reader().getLiveDocs());
if (scorer != null) {
int newDoc = scorer.advance(doc);
if (newDoc == doc) {
Added: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/BlockPhraseScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/BlockPhraseScorer.java?rev=1638805&view=auto
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/BlockPhraseScorer.java (added)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/BlockPhraseScorer.java Wed Nov 12 14:56:17 2014
@@ -0,0 +1,70 @@
+package org.apache.lucene.search.posfilter;
+
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.similarities.Similarity;
+
+import java.io.IOException;
+
+/*
+ * 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.
+ */
+
+public class BlockPhraseScorer extends PositionFilteredScorer {
+
+ private final Interval[] subIntervals;
+
+ public BlockPhraseScorer(Scorer filteredScorer, Similarity.SimScorer simScorer) {
+ super(filteredScorer, simScorer);
+ subIntervals = new Interval[subScorers.length];
+ for (int i = 0; i < subScorers.length; i++) {
+ subIntervals[i] = new Interval();
+ }
+ }
+
+ @Override
+ public void reset(int doc) throws IOException {
+ super.reset(doc);
+ for (int i = 0; i < subScorers.length; i++) {
+ subIntervals[i].reset();
+ }
+ }
+
+ @Override
+ protected int doNextPosition() throws IOException {
+ if (subScorers[0].nextPosition() == NO_MORE_POSITIONS)
+ return NO_MORE_POSITIONS;
+ subIntervals[0].update(subScorers[0]);
+ int i = 1;
+ while (i < subScorers.length) {
+ while (subIntervals[i].begin <= subIntervals[i - 1].end) {
+ if (subScorers[i].nextPosition() == NO_MORE_POSITIONS)
+ return NO_MORE_POSITIONS;
+ subIntervals[i].update(subScorers[i]);
+ }
+ if (subIntervals[i].begin == subIntervals[i - 1].end + 1) {
+ i++;
+ }
+ else {
+ if (subScorers[0].nextPosition() == NO_MORE_POSITIONS)
+ return NO_MORE_POSITIONS;
+ subIntervals[0].update(subScorers[0]);
+ i = 1;
+ }
+ }
+ current.update(subIntervals[0], subIntervals[subScorers.length - 1]);
+ return subScorers[0].startPosition();
+ }
+}
Added: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/Interval.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/Interval.java?rev=1638805&view=auto
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/Interval.java (added)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/Interval.java Wed Nov 12 14:56:17 2014
@@ -0,0 +1,200 @@
+package org.apache.lucene.search.posfilter;
+/*
+ * 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.index.DocsEnum;
+
+import java.io.IOException;
+
+/**
+ * Represents a section of a document that matches a query
+ */
+public class Interval implements Cloneable {
+
+ /** The position of the start of this Interval */
+ public int begin;
+
+ /** The position of the end of this Interval */
+ public int end;
+
+ /** The offset of the start of this Interval */
+ public int offsetBegin;
+
+ /** The offset of the end of this Interval */
+ public int offsetEnd;
+
+ /** An interval that will always compare as less than any other interval */
+ public static final Interval INFINITE_INTERVAL = new Interval();
+
+ /**
+ * Constructs a new Interval
+ * @param begin the start position
+ * @param end the end position
+ * @param offsetBegin the start offset
+ * @param offsetEnd the end offset
+ */
+ public Interval(int begin, int end, int offsetBegin, int offsetEnd) {
+ this.begin = begin;
+ this.end = end;
+ this.offsetBegin = offsetBegin;
+ this.offsetEnd = offsetEnd;
+ }
+
+ /**
+ * Constructs a new Interval with no initial values. This
+ * will always compare as less than any other Interval.
+ */
+ public Interval() {
+ this(Integer.MIN_VALUE, Integer.MIN_VALUE, -1, -1);
+ }
+
+ public Interval(DocsEnum docsEnum) throws IOException {
+ this.begin = docsEnum.startPosition();
+ this.end = docsEnum.endPosition();
+ this.offsetBegin = docsEnum.startOffset();
+ this.offsetEnd = docsEnum.endOffset();
+ }
+
+ /**
+ * Update to span the range defined by two other Intervals.
+ * @param start the first Interval
+ * @param end the second Interval
+ */
+ public void update(Interval start, Interval end) {
+ this.begin = start.begin;
+ this.offsetBegin = start.offsetBegin;
+ this.end = end.end;
+ this.offsetEnd = end.offsetEnd;
+ }
+
+ /**
+ * Compare with another Interval.
+ * @param other the comparator
+ * @return true if both start and end positions are less than
+ * the comparator.
+ */
+ public boolean lessThanExclusive(Interval other) {
+ return begin < other.begin && end < other.end;
+ }
+
+ /**
+ * Compare with another Interval.
+ * @param other the comparator
+ * @return true if both start and end positions are less than
+ * or equal to the comparator's.
+ */
+ public boolean lessThan(Interval other) {
+ return begin <= other.begin && end <= other.end;
+ }
+
+ /**
+ * Compare with another Interval
+ * @param other the comparator
+ * @return true if both start and end positions are greater then
+ * the comparator's.
+ */
+ public boolean greaterThanExclusive(Interval other) {
+ return begin > other.begin && end > other.end;
+ }
+
+ /**
+ * Compare with another Interval
+ * @param other the comparator
+ * @return true if both start and end positions are greater then
+ * of equal to the comparator's.
+ */
+ public boolean greaterThan(Interval other) {
+ return begin >= other.begin && end >= other.end;
+ }
+
+ /**
+ * Compare with another Interval
+ * @param other the comparator
+ * @return true if this Interval contains the comparator
+ */
+ public boolean contains(Interval other) {
+ return begin <= other.begin && other.end <= end;
+ }
+
+ /**
+ * Compare with another Interval to find overlaps
+ * @param other
+ * @return true if the two intervals overlap
+ */
+ public boolean overlaps(Interval other) {
+ return this.contains(other) || other.contains(this);
+ }
+
+ /**
+ * Set all values of this Interval to be equal to another's
+ * @param other the Interval to copy
+ */
+ public void copy(Interval other) {
+ begin = other.begin;
+ end = other.end;
+ offsetBegin = other.offsetBegin;
+ offsetEnd = other.offsetEnd;
+ }
+
+ /**
+ * Set to a state that will always compare as less than any
+ * other Interval.
+ */
+ public void reset() {
+ offsetBegin = offsetEnd = -1;
+ begin = end = Integer.MIN_VALUE;
+ }
+
+ /**
+ * Set to a state that will always compare as more than any
+ * other Interval.
+ */
+ public void setMaximum() {
+ offsetBegin = offsetEnd = -1;
+ begin = end = Integer.MAX_VALUE;
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(); // should not happen
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Interval [begin=" + begin + "(" + offsetBegin + "), end="
+ + end + "(" + offsetEnd + ")]";
+ }
+
+ public void update(DocsEnum docsEnum) throws IOException {
+ offsetBegin = docsEnum.startOffset();
+ offsetEnd = docsEnum.endOffset();
+ begin = docsEnum.startPosition();
+ end = docsEnum.endPosition();
+ }
+
+ public void update(Interval interval) {
+ this.begin = interval.begin;
+ this.end = interval.end;
+ this.offsetBegin = interval.offsetBegin;
+ this.offsetEnd = interval.offsetEnd;
+ }
+
+}
\ No newline at end of file
Added: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/NonOverlappingQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/NonOverlappingQuery.java?rev=1638805&view=auto
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/NonOverlappingQuery.java (added)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/NonOverlappingQuery.java Wed Nov 12 14:56:17 2014
@@ -0,0 +1,204 @@
+package org.apache.lucene.search.posfilter;
+
+/*
+ * 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.index.IndexReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.search.similarities.Similarity;
+import org.apache.lucene.util.Bits;
+
+import java.io.IOException;
+import java.util.Set;
+
+/**
+ * A Query that matches documents containing an interval (the minuend) that
+ * does not contain another interval (the subtrahend).
+ *
+ * As an example, given the following {@link org.apache.lucene.search.BooleanQuery}:
+ * <pre>
+ * BooleanQuery bq = new BooleanQuery();
+ * bq.add(new TermQuery(new Term(field, "quick")), BooleanQuery.Occur.MUST);
+ * bq.add(new TermQuery(new Term(field, "fox")), BooleanQuery.Occur.MUST);
+ * </pre>
+ *
+ * The document "the quick brown fox" will be matched by this query. But
+ * create a NonOverlappingQuery using this query as a minuend:
+ * <pre>
+ * NonOverlappingQuery brq = new NonOverlappingQuery(bq, new TermQuery(new Term(field, "brown")));
+ * </pre>
+ *
+ * This query will not match "the quick brown fox", because "brown" is found
+ * within the interval of the boolean query for "quick" and "fox. The query
+ * will match "the quick fox is brown", because here "brown" is outside
+ * the minuend's interval.
+ *
+ * N.B. Positions must be included in the index for this query to work
+ *
+ * Implements the Brouwerian operator as defined in <a href=
+ * "http://vigna.dsi.unimi.it/ftp/papers/EfficientAlgorithmsMinimalIntervalSemantics"
+ * >"Efficient Optimally Lazy Algorithms for Minimal-Interval Semantics"</a>
+ *
+ * @lucene.experimental
+ */
+public final class NonOverlappingQuery extends PositionFilterQuery {
+
+ private Query subtrahend;
+
+ /**
+ * Constructs a Query that matches documents containing intervals of the minuend
+ * that are not subtended by the subtrahend
+ * @param minuend the minuend Query
+ * @param subtrahend the subtrahend Query
+ */
+ public NonOverlappingQuery(Query minuend, Query subtrahend) {
+ super(minuend, new BrouwerianScorerFactory(subtrahend));
+ this.subtrahend = subtrahend;
+ }
+
+ @Override
+ public void extractTerms(Set<Term> terms) {
+ super.extractTerms(terms);
+ subtrahend.extractTerms(terms);
+ }
+
+ @Override
+ public Query rewrite(IndexReader reader) throws IOException {
+ Query rewrittenMinuend = innerQuery.rewrite(reader);
+ Query rewrittenSubtrahend = subtrahend.rewrite(reader);
+ if (rewrittenMinuend != innerQuery || rewrittenSubtrahend != subtrahend) {
+ return new NonOverlappingQuery(rewrittenMinuend, rewrittenSubtrahend);
+ }
+ return this;
+ }
+
+ private static class BrouwerianScorerFactory implements ScorerFilterFactory {
+
+ private final Query subtrahend;
+
+ BrouwerianScorerFactory(Query subtrahend) {
+ this.subtrahend = subtrahend;
+ }
+
+ @Override
+ public Scorer scorer(Scorer filteredScorer, Similarity.SimScorer simScorer) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getName() {
+ return "NonOverlapping[" + subtrahend.toString() + "]/";
+ }
+ }
+
+ @Override
+ public Weight createWeight(IndexSearcher searcher) throws IOException {
+ return new BrouwerianWeight(innerQuery.createWeight(searcher),
+ subtrahend.createWeight(searcher), searcher);
+ }
+
+ class BrouwerianWeight extends ScorerFilterWeight {
+
+ private final Weight subtrahendWeight;
+
+ public BrouwerianWeight(Weight minuendWeight, Weight subtrahendWeight, IndexSearcher searcher)
+ throws IOException {
+ super(minuendWeight, searcher);
+ this.subtrahendWeight = subtrahendWeight;
+ }
+
+ @Override
+ public Scorer scorer(LeafReaderContext context, int flags, Bits acceptDocs) throws IOException {
+ return new BrouwerianScorer(innerWeight.scorer(context, flags, acceptDocs),
+ subtrahendWeight.scorer(context, flags, acceptDocs),
+ similarity.simScorer(stats, context));
+ }
+ }
+
+ static class BrouwerianScorer extends PositionFilteredScorer {
+
+ private final Scorer subtrahend;
+ private Interval subtInterval = new Interval();
+ private int subtPosition = -1;
+
+ BrouwerianScorer(Scorer minuend, Scorer subtrahend, Similarity.SimScorer simScorer) {
+ super(minuend, simScorer);
+ this.subtrahend = subtrahend;
+ }
+
+ @Override
+ protected void reset(int doc) throws IOException {
+ super.reset(doc);
+ if (this.subtrahend == null || this.subtrahend.advance(doc) != doc)
+ subtPosition = NO_MORE_POSITIONS;
+ else
+ subtPosition = -1;
+ this.subtInterval.reset();
+ }
+
+ @Override
+ protected int doNextPosition() throws IOException {
+ if (subtPosition == NO_MORE_POSITIONS) {
+ int pos = child.nextPosition();
+ if (pos != NO_MORE_POSITIONS)
+ current.update(child);
+ return pos;
+ }
+ while (child.nextPosition() != NO_MORE_POSITIONS) {
+ current.update(child);
+ while (subtInterval.lessThanExclusive(current) &&
+ (subtPosition = subtrahend.nextPosition()) != NO_MORE_POSITIONS) {
+ subtInterval.update(subtrahend);
+ }
+ if (subtPosition == NO_MORE_POSITIONS || !current.overlaps(subtInterval))
+ return current.begin;
+ }
+ return NO_MORE_POSITIONS;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((innerQuery == null) ? 0 : innerQuery.hashCode());
+ result = prime * result
+ + ((subtrahend == null) ? 0 : subtrahend.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (!super.equals(obj)) return false;
+ if (getClass() != obj.getClass()) return false;
+ NonOverlappingQuery other = (NonOverlappingQuery) obj;
+ if (innerQuery == null) {
+ if (other.innerQuery != null) return false;
+ } else if (!innerQuery.equals(other.innerQuery)) return false;
+ if (subtrahend == null) {
+ if (other.subtrahend != null) return false;
+ } else if (!subtrahend.equals(other.subtrahend)) return false;
+ return true;
+ }
+
+}
\ No newline at end of file
Added: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/OrderedNearQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/OrderedNearQuery.java?rev=1638805&view=auto
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/OrderedNearQuery.java (added)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/OrderedNearQuery.java Wed Nov 12 14:56:17 2014
@@ -0,0 +1,139 @@
+package org.apache.lucene.search.posfilter;
+
+/*
+ * 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.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.similarities.Similarity;
+
+import java.io.IOException;
+
+/**
+ * A query that matches if a set of subqueries also match, and are within
+ * a given distance of each other within the document. The subqueries
+ * must appear in the document in order.
+ *
+ * N.B. Positions must be included in the index for this query to work
+ *
+ * Implements the AND< operator as defined in <a href=
+ * "http://vigna.dsi.unimi.it/ftp/papers/EfficientAlgorithmsMinimalIntervalSemantics"
+ * >"Efficient Optimally Lazy Algorithms for Minimal-Interval Semantics"</a>
+ *
+ * @lucene.experimental
+ */
+
+public class OrderedNearQuery extends PositionFilterQuery {
+
+ /**
+ * Constructs an OrderedNearQuery
+ * @param slop the maximum distance between the subquery matches
+ * @param subqueries the subqueries to match.
+ */
+ public OrderedNearQuery(int slop, Query... subqueries) {
+ super(buildBooleanQuery(subqueries), new OrderedNearScorerFactory(slop));
+ }
+
+ private static class OrderedNearScorerFactory implements ScorerFilterFactory {
+
+ private final int slop;
+
+ public OrderedNearScorerFactory(int slop) {
+ this.slop = slop;
+ }
+
+ @Override
+ public Scorer scorer(Scorer filteredScorer, Similarity.SimScorer simScorer) {
+ return new WithinFilteredScorer(new OrderedNearScorer(filteredScorer, simScorer), slop, simScorer);
+ }
+
+ @Override
+ public String getName() {
+ return "OrderedNear/" + slop;
+ }
+ }
+
+ private static class OrderedNearScorer extends PositionFilteredScorer {
+
+ private final int lastiter;
+
+ private int index = 1;
+ private Interval[] intervals;
+
+ public OrderedNearScorer(Scorer filteredScorer, Similarity.SimScorer simScorer) {
+ super(filteredScorer, simScorer);
+ intervals = new Interval[subScorers.length];
+ for (int i = 0; i < subScorers.length; i++) {
+ intervals[i] = new Interval();
+ }
+ lastiter = intervals.length - 1;
+ }
+
+ @Override
+ public int freq() throws IOException {
+ return 1; // nocommit
+ }
+
+ @Override
+ protected void reset(int doc) throws IOException {
+ for (int i = 0; i < subScorers.length; i++) {
+ assert subScorers[i].docID() == doc;
+ intervals[i].update(Interval.INFINITE_INTERVAL);
+ }
+ if (subScorers[0].nextPosition() == NO_MORE_POSITIONS)
+ intervals[0].setMaximum();
+ else
+ intervals[0].update(subScorers[0]);
+ index = 1;
+ }
+
+ @Override
+ protected int doNextPosition() throws IOException {
+ if (intervals[0].begin == NO_MORE_POSITIONS)
+ return NO_MORE_POSITIONS;
+ current.setMaximum();
+ int b = Integer.MAX_VALUE;
+ while (true) {
+ while (true) {
+ final Interval previous = intervals[index - 1];
+ if (previous.end >= b) {
+ return current.begin;
+ }
+ if (index == intervals.length || intervals[index].begin > previous.end)
+ break;
+ Interval scratch = intervals[index];
+ do {
+ if (scratch.end >= b || subScorers[index].nextPosition() == NO_MORE_POSITIONS)
+ return current.begin;
+ intervals[index].update(subScorers[index]);
+ scratch = intervals[index];
+ } while (scratch.begin <= previous.end);
+ index++;
+ }
+ current.update(intervals[0], intervals[lastiter]);
+ matchDistance = (intervals[lastiter].begin - lastiter) - intervals[0].end;
+ b = intervals[lastiter].begin;
+ index = 1;
+ if (subScorers[0].nextPosition() == NO_MORE_POSITIONS) {
+ intervals[0].setMaximum();
+ return current.begin;
+ }
+ intervals[0].update(subScorers[0]);
+ }
+ }
+ }
+}
Added: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/PositionFilterQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/PositionFilterQuery.java?rev=1638805&view=auto
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/PositionFilterQuery.java (added)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/PositionFilterQuery.java Wed Nov 12 14:56:17 2014
@@ -0,0 +1,164 @@
+package org.apache.lucene.search.posfilter;
+
+/*
+ * 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.index.DocsEnum;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermContext;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.ComplexExplanation;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.TermStatistics;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.search.similarities.Similarity;
+import org.apache.lucene.util.Bits;
+
+import java.io.IOException;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class PositionFilterQuery extends Query {
+
+ protected final Query innerQuery;
+ protected final ScorerFilterFactory scorerFilterFactory;
+
+ public PositionFilterQuery(Query innerQuery, ScorerFilterFactory scorerFilterFactory) {
+ this.innerQuery = innerQuery;
+ this.scorerFilterFactory = scorerFilterFactory;
+ }
+
+ protected static BooleanQuery buildBooleanQuery(Query... queries) {
+ BooleanQuery bq = new BooleanQuery();
+ for (Query q : queries) {
+ bq.add(q, BooleanClause.Occur.MUST);
+ }
+ return bq;
+ }
+
+ @Override
+ public void extractTerms(Set<Term> terms) {
+ innerQuery.extractTerms(terms);
+ }
+
+ @Override
+ public Query rewrite(IndexReader reader) throws IOException {
+ Query rewritten = innerQuery.rewrite(reader);
+ if (rewritten != innerQuery) {
+ return new PositionFilterQuery(rewritten, scorerFilterFactory);
+ }
+ return this;
+ }
+
+ @Override
+ public Weight createWeight(IndexSearcher searcher) throws IOException {
+ return new ScorerFilterWeight(innerQuery.createWeight(searcher), searcher);
+ }
+
+ @Override
+ public String toString(String field) {
+ return scorerFilterFactory.getName() + "[" + innerQuery.toString() + "]";
+ }
+
+ public class ScorerFilterWeight extends Weight {
+
+ protected final Weight innerWeight;
+ protected final Similarity similarity;
+ protected final Similarity.SimWeight stats;
+
+ public ScorerFilterWeight(Weight innerWeight, IndexSearcher searcher) throws IOException {
+ this.innerWeight = innerWeight;
+ this.similarity = searcher.getSimilarity();
+ this.stats = getSimWeight(innerWeight.getQuery(), searcher);
+ }
+
+ private Similarity.SimWeight getSimWeight(Query query, IndexSearcher searcher) throws IOException {
+ TreeSet<Term> terms = new TreeSet<Term>();
+ query.extractTerms(terms);
+ if (terms.size() == 0)
+ return null;
+ int i = 0;
+ TermStatistics[] termStats = new TermStatistics[terms.size()];
+ for (Term term : terms) {
+ TermContext state = TermContext.build(searcher.getTopReaderContext(), term);
+ termStats[i] = searcher.termStatistics(term, state);
+ i++;
+ }
+ final String field = terms.first().field(); // nocommit - should we be checking all filtered terms
+ // are on the same field?
+ return similarity.computeWeight(query.getBoost(), searcher.collectionStatistics(field), termStats);
+ }
+
+ @Override
+ public Explanation explain(LeafReaderContext context, int doc) throws IOException {
+ Scorer scorer = scorer(context, DocsEnum.FLAG_POSITIONS, context.reader().getLiveDocs());
+ if (scorer != null) {
+ int newDoc = scorer.advance(doc);
+ if (newDoc == doc) {
+ float freq = scorer.freq();
+ Similarity.SimScorer docScorer = similarity.simScorer(stats, context);
+ ComplexExplanation result = new ComplexExplanation();
+ result.setDescription("weight("+getQuery()+" in "+doc+") [" + similarity.getClass().getSimpleName() + "], result of:");
+ Explanation scoreExplanation = docScorer.explain(doc, new Explanation(freq, "phraseFreq=" + freq));
+ result.addDetail(scoreExplanation);
+ result.setValue(scoreExplanation.getValue());
+ result.setMatch(true);
+ return result;
+ }
+ }
+ return new ComplexExplanation(false, 0.0f,
+ "No matching term within position filter");
+ }
+
+ @Override
+ public Query getQuery() {
+ return PositionFilterQuery.this;
+ }
+
+ @Override
+ public float getValueForNormalization() throws IOException {
+ return stats == null ? 1.0f : stats.getValueForNormalization();
+ }
+
+ @Override
+ public void normalize(float norm, float topLevelBoost) {
+ if (stats != null)
+ stats.normalize(norm, topLevelBoost);
+ }
+
+ @Override
+ public Scorer scorer(LeafReaderContext context, int flags, Bits acceptDocs) throws IOException {
+ Scorer filteredScorer = innerWeight.scorer(context, flags | DocsEnum.FLAG_POSITIONS, acceptDocs);
+ return filteredScorer == null ? null
+ : scorerFilterFactory.scorer(filteredScorer, similarity.simScorer(stats, context));
+ }
+ }
+
+ public static interface ScorerFilterFactory {
+
+ public Scorer scorer(Scorer filteredScorer, Similarity.SimScorer simScorer);
+
+ public String getName();
+
+ }
+}
Added: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/PositionFilteredScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/PositionFilteredScorer.java?rev=1638805&view=auto
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/PositionFilteredScorer.java (added)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/PositionFilteredScorer.java Wed Nov 12 14:56:17 2014
@@ -0,0 +1,137 @@
+package org.apache.lucene.search.posfilter;
+
+/*
+ * 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.search.Scorer;
+import org.apache.lucene.search.similarities.Similarity;
+
+import java.io.IOException;
+
+public abstract class PositionFilteredScorer extends Scorer {
+
+ protected final Scorer[] subScorers;
+ protected final Scorer child;
+ protected final Interval current = new Interval();
+ protected final Similarity.SimScorer simScorer;
+ protected int matchDistance;
+
+ private boolean buffered;
+
+ public PositionFilteredScorer(Scorer filteredScorer, Similarity.SimScorer simScorer) {
+ super(filteredScorer.getWeight());
+ this.simScorer = simScorer;
+ child = filteredScorer;
+ subScorers = new Scorer[filteredScorer.getChildren().size()];
+ int i = 0;
+ for (ChildScorer subScorer : filteredScorer.getChildren()) {
+ subScorers[i++] = subScorer.child;
+ }
+ }
+
+ @Override
+ public float score() throws IOException {
+ return this.simScorer.score(docID(), freq());
+ }
+
+ @Override
+ public int docID() {
+ return child.docID();
+ }
+
+ @Override
+ public int freq() throws IOException {
+ int freq = 0;
+ while (nextPosition() != NO_MORE_POSITIONS) {
+ freq++;
+ }
+ return freq;
+ }
+
+ @Override
+ public int nextDoc() throws IOException {
+ while (child.nextDoc() != NO_MORE_DOCS) {
+ reset(child.docID());
+ if (nextPosition() != NO_MORE_POSITIONS) {
+ buffered = true;
+ return child.docID();
+ }
+ }
+ return NO_MORE_DOCS;
+ }
+
+ @Override
+ public int advance(int target) throws IOException {
+ if (child.advance(target) == NO_MORE_DOCS)
+ return NO_MORE_DOCS;
+ do {
+ reset(child.docID());
+ if (nextPosition() != NO_MORE_POSITIONS) {
+ buffered = true;
+ return child.docID();
+ }
+ } while (child.nextDoc() != NO_MORE_DOCS);
+ return NO_MORE_DOCS;
+ }
+
+ @Override
+ public int nextPosition() throws IOException {
+ if (buffered) {
+ //System.out.println(this.hashCode() + ": returning buffered nextPos");
+ buffered = false;
+ return current.begin;
+ }
+ //System.out.println(this.hashCode() + ": returning unbuffered nextPos");
+ return doNextPosition();
+ }
+
+ protected abstract int doNextPosition() throws IOException;
+
+ protected void reset(int doc) throws IOException {
+ buffered = false;
+ };
+
+ public int getMatchDistance() {
+ return matchDistance;
+ }
+
+ @Override
+ public int startPosition() throws IOException {
+ return current.begin;
+ }
+
+ @Override
+ public int endPosition() throws IOException {
+ return current.end;
+ }
+
+ @Override
+ public int startOffset() throws IOException {
+ return current.offsetBegin;
+ }
+
+ @Override
+ public int endOffset() throws IOException {
+ return current.offsetEnd;
+ }
+
+ @Override
+ public long cost() {
+ return child.cost();
+ }
+// nocommit Payloads - need to add these to Interval?
+}
Added: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/RangeFilterQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/RangeFilterQuery.java?rev=1638805&view=auto
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/RangeFilterQuery.java (added)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/RangeFilterQuery.java Wed Nov 12 14:56:17 2014
@@ -0,0 +1,82 @@
+package org.apache.lucene.search.posfilter;
+
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.similarities.Similarity;
+
+import java.io.IOException;
+
+/**
+ * Copyright (c) 2012 Lemur Consulting Ltd.
+ * <p/>
+ * Licensed 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ */
+
+public class RangeFilterQuery extends PositionFilterQuery {
+
+ public RangeFilterQuery(int start, int end, Query innerQuery) {
+ super(innerQuery, new RangeFilterScorerFactory(start, end));
+ }
+
+ public RangeFilterQuery(int end, Query innerQuery) {
+ this(0, end, innerQuery);
+ }
+
+ private static class RangeFilterScorerFactory implements ScorerFilterFactory {
+
+ private final int start;
+ private final int end;
+
+ public RangeFilterScorerFactory(int start, int end) {
+ this.start = start;
+ this.end = end;
+ }
+
+ @Override
+ public Scorer scorer(Scorer filteredScorer, Similarity.SimScorer simScorer) {
+ return new RangeFilterScorer(start, end, filteredScorer, simScorer);
+ }
+
+ @Override
+ public String getName() {
+ return "RangeFilter(" + start + "," + end + ")";
+ }
+ }
+
+ private static class RangeFilterScorer extends PositionFilteredScorer {
+
+ private final int start;
+ private final int end;
+
+ public RangeFilterScorer(int start, int end, Scorer filteredScorer, Similarity.SimScorer simScorer) {
+ super(filteredScorer, simScorer);
+ this.start = start;
+ this.end = end;
+ }
+
+ @Override
+ protected int doNextPosition() throws IOException {
+ int position;
+ while ((position = child.nextPosition()) != NO_MORE_POSITIONS) {
+ if (position > end)
+ return NO_MORE_POSITIONS;
+ if (position >= start) {
+ current.update(child);
+ return position;
+ }
+ }
+ return NO_MORE_POSITIONS;
+ }
+ }
+
+}
Added: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/UnorderedNearQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/UnorderedNearQuery.java?rev=1638805&view=auto
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/UnorderedNearQuery.java (added)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/UnorderedNearQuery.java Wed Nov 12 14:56:17 2014
@@ -0,0 +1,187 @@
+package org.apache.lucene.search.posfilter;
+
+/**
+ * Copyright (c) 2012 Lemur Consulting Ltd.
+ * <p/>
+ * Licensed 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.index.DocsEnum;
+import org.apache.lucene.search.PositionQueue;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.similarities.Similarity;
+
+import java.io.IOException;
+
+/**
+ * A query that matches if a set of subqueries also match, and are within
+ * a given distance of each other within the document. The subqueries
+ * may appear in the document in any order.
+ *
+ * N.B. Positions must be included in the index for this query to work
+ *
+ * Implements the LOWPASS<sub>k</sub> operator as defined in <a href=
+ * "http://vigna.dsi.unimi.it/ftp/papers/EfficientAlgorithmsMinimalIntervalSemantics"
+ * >"Efficient Optimally Lazy Algorithms for Minimal-Interval Semantics"</a>
+ *
+ * @lucene.experimental
+ */
+
+public class UnorderedNearQuery extends PositionFilterQuery {
+
+ /**
+ * Constructs an OrderedNearQuery
+ * @param slop the maximum distance between the subquery matches
+ * @param subqueries the subqueries to match.
+ */
+ public UnorderedNearQuery(int slop, Query... subqueries) {
+ super(buildBooleanQuery(subqueries), new UnorderedNearScorerFactory(slop));
+ }
+
+ private static class UnorderedNearScorerFactory implements ScorerFilterFactory {
+
+ private final int slop;
+
+ UnorderedNearScorerFactory(int slop) {
+ this.slop = slop;
+ }
+
+ @Override
+ public Scorer scorer(Scorer filteredScorer, Similarity.SimScorer simScorer) {
+ return new WithinFilteredScorer(new UnorderedNearScorer(filteredScorer, simScorer), slop, simScorer);
+ }
+
+ @Override
+ public String getName() {
+ return "UnorderedNear/" + slop;
+ }
+ }
+
+ private static class UnorderedNearScorer extends PositionFilteredScorer {
+
+ SpanningPositionQueue posQueue;
+
+ public UnorderedNearScorer(Scorer filteredScorer, Similarity.SimScorer simScorer) {
+ super(filteredScorer, simScorer);
+ posQueue = new SpanningPositionQueue(subScorers);
+ }
+
+ @Override
+ protected int doNextPosition() throws IOException {
+ while (posQueue.isFull() && posQueue.span.begin == current.begin) {
+ posQueue.nextPosition();
+ }
+ if (!posQueue.isFull())
+ return NO_MORE_POSITIONS;
+ do {
+ //current.update(posQueue.top().interval, posQueue.span);
+ posQueue.updateCurrent(current);
+ if (current.equals(posQueue.top().interval))
+ return current.begin;
+ matchDistance = posQueue.getMatchDistance();
+ posQueue.nextPosition();
+ } while (posQueue.isFull() && current.end == posQueue.span.end);
+ return current.begin;
+ }
+
+ @Override
+ protected void reset(int doc) throws IOException {
+ super.reset(doc);
+ current.reset();
+ posQueue.advanceTo(doc);
+ }
+
+ }
+
+ private static class SpanningPositionQueue extends PositionQueue {
+
+ Interval span = new Interval();
+ int scorerCount;
+ int firstIntervalEnd;
+ int lastIntervalBegin;
+
+ public SpanningPositionQueue(Scorer[] subScorers) {
+ super(subScorers);
+ scorerCount = subScorers.length;
+ }
+
+ public int getMatchDistance() {
+ return lastIntervalBegin - firstIntervalEnd - scorerCount + 1;
+ }
+
+ public boolean isFull() {
+ return queuesize == scorerCount;
+ }
+
+ public void updateCurrent(Interval current) {
+ final Interval top = this.top().interval;
+ current.update(top, span);
+ this.firstIntervalEnd = top.end;
+ }
+
+ private void updateRightExtreme(Interval newRight) {
+ if (span.end <= newRight.end) {
+ span.update(span, newRight);
+ this.lastIntervalBegin = newRight.begin;
+ }
+ }
+
+ protected void updateInternalIntervals() {
+ updateRightExtreme(top().interval);
+ }
+
+ @Override
+ public int nextPosition() throws IOException {
+ int position;
+ if ((position = super.nextPosition()) == DocsEnum.NO_MORE_POSITIONS) {
+ return DocsEnum.NO_MORE_POSITIONS;
+ }
+ span.update(top().interval, span);
+ return position;
+ }
+
+ @Override
+ protected void init() throws IOException {
+ super.init();
+ for (Object docsEnumRef : getHeapArray()) {
+ if (docsEnumRef != null) {
+ final Interval i = ((DocsEnumRef) docsEnumRef).interval;
+ updateRightExtreme(i);
+ }
+ }
+ }
+
+ @Override
+ public void advanceTo(int doc) {
+ super.advanceTo(doc);
+ span.reset();
+ firstIntervalEnd = lastIntervalBegin = span.begin;
+ }
+
+ @Override
+ protected boolean lessThan(DocsEnumRef left, DocsEnumRef right) {
+ final Interval a = left.interval;
+ final Interval b = right.interval;
+ return a.begin < b.begin || (a.begin == b.begin && a.end > b.end);
+ }
+
+ @Override
+ public String toString() {
+ return top().interval.toString();
+ }
+ }
+
+
+}
+
Added: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/WithinFilteredScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/WithinFilteredScorer.java?rev=1638805&view=auto
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/WithinFilteredScorer.java (added)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/posfilter/WithinFilteredScorer.java Wed Nov 12 14:56:17 2014
@@ -0,0 +1,47 @@
+package org.apache.lucene.search.posfilter;
+
+/*
+ * 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.search.similarities.Similarity;
+
+import java.io.IOException;
+
+public class WithinFilteredScorer extends PositionFilteredScorer {
+
+ private final int slop;
+ private final PositionFilteredScorer wrappedScorer;
+
+ public WithinFilteredScorer(PositionFilteredScorer wrappedScorer, int slop, Similarity.SimScorer simScorer) {
+ super(wrappedScorer, simScorer);
+ this.slop = slop;
+ this.wrappedScorer = wrappedScorer;
+ }
+
+ @Override
+ protected int doNextPosition() throws IOException {
+ int position;
+ while ((position = wrappedScorer.nextPosition()) != NO_MORE_POSITIONS) {
+ if (wrappedScorer.getMatchDistance() <= slop) {
+ current.update(wrappedScorer);
+ return position;
+ }
+ }
+ return NO_MORE_POSITIONS;
+ }
+
+}
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/similarities/Similarity.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/similarities/Similarity.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/similarities/Similarity.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/similarities/Similarity.java Wed Nov 12 14:56:17 2014
@@ -17,10 +17,8 @@ package org.apache.lucene.search.similar
* limitations under the License.
*/
-import java.io.IOException;
-
-import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.FieldInvertState;
+import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.CollectionStatistics;
import org.apache.lucene.search.Explanation;
@@ -28,9 +26,11 @@ import org.apache.lucene.search.IndexSea
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermStatistics;
-import org.apache.lucene.search.spans.SpanQuery; // javadoc
+import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.SmallFloat; // javadoc
+import org.apache.lucene.util.SmallFloat;
+
+import java.io.IOException;
/**
* Similarity defines the components of Lucene scoring.
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java Wed Nov 12 14:56:17 2014
@@ -17,12 +17,12 @@ package org.apache.lucene.search.spans;
* limitations under the License.
*/
-import java.io.IOException;
-
-import org.apache.lucene.search.Weight;
import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
import org.apache.lucene.search.similarities.Similarity;
+import java.io.IOException;
+
/**
* Public for extension only.
*/
@@ -96,16 +96,22 @@ public class SpanScorer extends Scorer {
public int freq() throws IOException {
return numMatches;
}
-
+
+ @Override
+ public int nextPosition() throws IOException {
+ return -1; // nocommit maybe I can coerce this into working?
+ }
+
/** Returns the intermediate "sloppy freq" adjusted for edit distance
* @lucene.internal */
// only public so .payloads can see it.
public float sloppyFreq() throws IOException {
return freq;
}
-
+
@Override
public long cost() {
return spans.cost();
}
+
}
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java Wed Nov 12 14:56:17 2014
@@ -20,7 +20,7 @@ package org.apache.lucene.search.spans;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Fields;
import org.apache.lucene.index.Term;
-import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.index.TermContext;
import org.apache.lucene.index.TermState;
import org.apache.lucene.index.Terms;
@@ -120,7 +120,7 @@ public class SpanTermQuery extends SpanQ
final TermsEnum termsEnum = context.reader().terms(term.field()).iterator(null);
termsEnum.seekExact(term.bytes(), state);
- final DocsAndPositionsEnum postings = termsEnum.docsAndPositions(acceptDocs, null, DocsAndPositionsEnum.FLAG_PAYLOADS);
+ final DocsEnum postings = termsEnum.docsAndPositions(acceptDocs, null, DocsEnum.FLAG_PAYLOADS);
if (postings != null) {
return new TermSpans(postings, term);
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java Wed Nov 12 14:56:17 2014
@@ -17,11 +17,18 @@ package org.apache.lucene.search.spans;
* limitations under the License.
*/
-import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.index.IndexReaderContext;
+import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext;
-import org.apache.lucene.search.*;
+import org.apache.lucene.search.ComplexExplanation;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.TermStatistics;
+import org.apache.lucene.search.Weight;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.search.similarities.Similarity.SimScorer;
import org.apache.lucene.util.Bits;
@@ -81,7 +88,7 @@ public class SpanWeight extends Weight {
}
@Override
- public Scorer scorer(LeafReaderContext context, Bits acceptDocs) throws IOException {
+ public Scorer scorer(LeafReaderContext context, int flags, Bits acceptDocs) throws IOException {
if (stats == null) {
return null;
} else {
@@ -91,7 +98,7 @@ public class SpanWeight extends Weight {
@Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
- SpanScorer scorer = (SpanScorer) scorer(context, context.reader().getLiveDocs());
+ SpanScorer scorer = (SpanScorer) scorer(context, DocsEnum.FLAG_POSITIONS, context.reader().getLiveDocs());
if (scorer != null) {
int newDoc = scorer.advance(doc);
if (newDoc == doc) {
Modified: lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java Wed Nov 12 14:56:17 2014
@@ -17,7 +17,7 @@ package org.apache.lucene.search.spans;
import org.apache.lucene.index.Term;
-import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.util.BytesRef;
@@ -30,7 +30,7 @@ import java.util.Collection;
* Public for extension only
*/
public class TermSpans extends Spans {
- protected final DocsAndPositionsEnum postings;
+ protected final DocsEnum postings;
protected final Term term;
protected int doc;
protected int freq;
@@ -38,7 +38,7 @@ public class TermSpans extends Spans {
protected int position;
protected boolean readPayload;
- public TermSpans(DocsAndPositionsEnum postings, Term term) {
+ public TermSpans(DocsEnum postings, Term term) {
this.postings = postings;
this.term = term;
doc = -1;
@@ -132,7 +132,7 @@ public class TermSpans extends Spans {
(doc == -1 ? "START" : (doc == Integer.MAX_VALUE) ? "END" : doc + "-" + position);
}
- public DocsAndPositionsEnum getPostings() {
+ public DocsEnum getPostings() {
return postings;
}
Modified: lucene/dev/lucene2878/lucene/core/src/test/org/apache/lucene/analysis/TestCachingTokenFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/test/org/apache/lucene/analysis/TestCachingTokenFilter.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/test/org/apache/lucene/analysis/TestCachingTokenFilter.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/test/org/apache/lucene/analysis/TestCachingTokenFilter.java Wed Nov 12 14:56:17 2014
@@ -26,7 +26,7 @@ import org.apache.lucene.document.Docume
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiFields;
-import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.store.Directory;
@@ -72,7 +72,7 @@ public class TestCachingTokenFilter exte
writer.addDocument(doc);
IndexReader reader = writer.getReader();
- DocsAndPositionsEnum termPositions = MultiFields.getTermPositionsEnum(reader,
+ DocsEnum termPositions = MultiFields.getTermPositionsEnum(reader,
MultiFields.getLiveDocs(reader),
"preanalyzed",
new BytesRef("term1"));
Modified: lucene/dev/lucene2878/lucene/core/src/test/org/apache/lucene/analysis/TestMockAnalyzer.java
URL: http://svn.apache.org/viewvc/lucene/dev/lucene2878/lucene/core/src/test/org/apache/lucene/analysis/TestMockAnalyzer.java?rev=1638805&r1=1638804&r2=1638805&view=diff
==============================================================================
--- lucene/dev/lucene2878/lucene/core/src/test/org/apache/lucene/analysis/TestMockAnalyzer.java (original)
+++ lucene/dev/lucene2878/lucene/core/src/test/org/apache/lucene/analysis/TestMockAnalyzer.java Wed Nov 12 14:56:17 2014
@@ -17,15 +17,10 @@ package org.apache.lucene.analysis;
* limitations under the License.
*/
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.Arrays;
-import java.util.Random;
-
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
-import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.index.Fields;
import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.LeafReader;
@@ -40,6 +35,11 @@ import org.apache.lucene.util.automaton.
import org.apache.lucene.util.automaton.Operations;
import org.apache.lucene.util.automaton.RegExp;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.Random;
+
import static org.apache.lucene.util.automaton.Operations.DEFAULT_MAX_DETERMINIZED_STATES;
public class TestMockAnalyzer extends BaseTokenStreamTestCase {
@@ -321,7 +321,7 @@ public class TestMockAnalyzer extends Ba
final Terms terms = fields.terms("f");
final TermsEnum te = terms.iterator(null);
assertEquals(new BytesRef("a"), te.next());
- final DocsAndPositionsEnum dpe = te.docsAndPositions(null, null);
+ final DocsEnum dpe = te.docsAndPositions(null, null);
assertEquals(0, dpe.nextDoc());
assertEquals(2, dpe.freq());
assertEquals(0, dpe.nextPosition());