MultipleDistanceQuery
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java
index 634a887..e219818 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java
@@ -12,19 +12,19 @@
import de.ids_mannheim.korap.query.spans.ElementDistanceSpans;
import de.ids_mannheim.korap.query.spans.TokenDistanceSpans;
-import de.ids_mannheim.korap.query.spans.UnorderedDistanceSpans;
import de.ids_mannheim.korap.query.spans.UnorderedElementDistanceSpans;
import de.ids_mannheim.korap.query.spans.UnorderedTokenDistanceSpans;
-/** Match two ordered Spans with minimum and maximum distance constraints.
- * The distance unit can be word (token), sentence or paragraph.
+/** Match two ordered or unordered Spans with minimum and maximum
+ * distance constraints. The distance unit can be word (token),
+ * sentence or paragraph.
*
* @author margaretha
* */
public class SpanDistanceQuery extends SimpleSpanQuery {
protected int minDistance, maxDistance;
- protected boolean isOrdered, collectPayloads;
+ public boolean isOrdered, collectPayloads;
protected SpanQuery firstClause, secondClause;
private SpanQuery elementQuery; // element distance unit
@@ -52,11 +52,6 @@
this.collectPayloads = collectPayloads;
this.elementQuery = elementQuery;
}
-
- public SpanDistanceQuery(SpanQuery firstClause2, SpanQuery secondClause2,
- String string) {
- super(firstClause2, secondClause2, string);
- }
@Override
public SpanDistanceQuery clone() {
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanMultipleDistanceQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanMultipleDistanceQuery.java
new file mode 100644
index 0000000..4fac9e6
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanMultipleDistanceQuery.java
@@ -0,0 +1,107 @@
+package de.ids_mannheim.korap.query;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermContext;
+import org.apache.lucene.search.spans.SpanQuery;
+import org.apache.lucene.search.spans.Spans;
+import org.apache.lucene.util.Bits;
+
+import de.ids_mannheim.korap.query.spans.MultipleDistanceSpans;
+
+/** Match two spans with respect to a list of distance constraints.
+ * No repetition of constraints of the same type is allowed. For example,
+ * there must only exactly one constraint for word/token-based distance.
+ *
+ * @author margaretha
+ * */
+public class SpanMultipleDistanceQuery extends SimpleSpanQuery{
+
+ private SpanQuery firstClause, secondClause;
+ private List<DistanceConstraint> constraints;
+ private boolean isOrdered;
+ private boolean collectPayloads;
+
+ public SpanMultipleDistanceQuery(SpanQuery firstClause, SpanQuery secondClause,
+ List<DistanceConstraint> constraints, boolean isOrdered,
+ boolean collectPayloads) {
+ super(firstClause, secondClause, "spanMultipleDistance");
+ this.constraints = constraints;
+ this.firstClause=firstClause;
+ this.secondClause=secondClause;
+ this.isOrdered = isOrdered;
+ this.collectPayloads = collectPayloads;
+ }
+
+ @Override
+ public SpanMultipleDistanceQuery clone() {
+ SpanMultipleDistanceQuery query = new SpanMultipleDistanceQuery(
+ (SpanQuery) firstClause.clone(),
+ (SpanQuery) secondClause.clone(),
+ this.constraints,
+ this.isOrdered,
+ this.collectPayloads
+ );
+
+ query.setBoost(getBoost());
+ return query;
+ }
+
+ /** Filter the span matches of each constraint, returning only the matches
+ * meeting all the constraints.
+ * @return only the span matches meeting all the constraints.
+ * */
+ @Override
+ public Spans getSpans(AtomicReaderContext context, Bits acceptDocs,
+ Map<Term, TermContext> termContexts) throws IOException {
+
+ DistanceConstraint c;
+ SpanDistanceQuery sdq,sdq2;
+ Spans ds,ds2;
+ MultipleDistanceSpans mds = null;
+
+ c = constraints.get(0);
+ sdq = createSpanDistanceQuery(c);
+ ds = sdq.getSpans(context, acceptDocs, termContexts);
+
+ for (int i=1; i< constraints.size(); i++){
+ sdq2 = createSpanDistanceQuery(constraints.get(i));
+ ds2 = sdq2.getSpans(context, acceptDocs, termContexts);
+
+ mds = new MultipleDistanceSpans(this, context, acceptDocs,
+ termContexts, ds, ds2, isOrdered);
+ ds = mds;
+ }
+
+ return mds;
+ }
+
+ /** Create a SpanDistanceQuery based on the given constraint.
+ * @return a SpanDistanceQuery
+ * */
+ private SpanDistanceQuery createSpanDistanceQuery(DistanceConstraint c) {
+
+ if (c.getUnit().equals("w")){
+ return new SpanDistanceQuery(firstClause, secondClause,
+ c.getMinDistance(), c.getMaxDistance(),isOrdered,
+ collectPayloads);
+ }
+
+ return new SpanDistanceQuery(c.getElementQuery(), firstClause,
+ secondClause, c.getMinDistance(), c.getMaxDistance(),
+ isOrdered, collectPayloads);
+ }
+
+ public List<DistanceConstraint> getConstraints() {
+ return constraints;
+ }
+
+ public void setConstraints(List<DistanceConstraint> constraints) {
+ this.constraints = constraints;
+ }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/DistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/DistanceSpans.java
index 6bc0c23..aedd6c1 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/DistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/DistanceSpans.java
@@ -24,11 +24,11 @@
* @author margaretha
* */
public abstract class DistanceSpans extends SimpleSpans{
-
+
protected CandidateSpan matchFirstSpan,matchSecondSpan;
protected Logger log = LoggerFactory.getLogger(DistanceSpans.class);
- public DistanceSpans(SpanDistanceQuery query,
+ public DistanceSpans(SimpleSpanQuery query,
AtomicReaderContext context, Bits acceptDocs,
Map<Term, TermContext> termContexts) throws IOException {
super(query, context, acceptDocs, termContexts);
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/MultipleDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/MultipleDistanceSpans.java
new file mode 100644
index 0000000..f9c5e68
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/MultipleDistanceSpans.java
@@ -0,0 +1,125 @@
+package de.ids_mannheim.korap.query.spans;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermContext;
+import org.apache.lucene.search.spans.Spans;
+import org.apache.lucene.util.Bits;
+
+import de.ids_mannheim.korap.query.SimpleSpanQuery;
+
+/** Span enumeration of matches whose two sub-spans has exactly the same
+ * first and second sub-sub-spans. This class basically filters the span
+ * matches of its child spans.
+ *
+ * @author margaretha
+ * */
+public class MultipleDistanceSpans extends DistanceSpans{
+
+ private DistanceSpans x,y;
+ private boolean isOrdered;
+
+ public MultipleDistanceSpans(SimpleSpanQuery query,
+ AtomicReaderContext context, Bits acceptDocs,
+ Map<Term, TermContext> termContexts,
+ Spans firstSpans, Spans secondSpans, boolean isOrdered)
+ throws IOException {
+ super(query, context, acceptDocs, termContexts);
+ this.isOrdered =isOrdered;
+ x = (DistanceSpans) firstSpans;
+ y = (DistanceSpans) secondSpans;
+ hasMoreSpans = x.next() && y.next();
+ }
+
+ @Override
+ public boolean next() throws IOException {
+ isStartEnumeration=false;
+ matchPayload.clear();
+ return advance();
+ }
+
+ /** Find the next match.
+ * */
+ protected boolean advance() throws IOException {
+
+ while (hasMoreSpans && ensureSameDoc(x, y)){
+ if (findMatch()){
+ advanceChild();
+ return true;
+ }
+ advanceChild();
+ }
+ return false;
+ }
+
+ /** Find the next match of one of the sub/child-span.
+ * */
+ private void advanceChild() throws IOException{
+ if (isOrdered){
+ if (x.end() < y.end() ||
+ (x.end() == y.end() && x.start() < y.start()) )
+ hasMoreSpans = x.next();
+ else hasMoreSpans = y.next();
+ }
+ // The matches of unordered distance spans are ordered by the
+ // start position
+ else {
+ if (x.start() < y.start() ||
+ (x.start() == y.start() && x.end() < y.end()) )
+ hasMoreSpans = x.next();
+ else hasMoreSpans = y.next();
+ }
+ }
+
+ /** Check if the sub-spans of x and y having exactly the same position.
+ * This is basically an AND operation.
+ * @return true iff the sub-spans are identical.
+ * */
+ protected boolean findMatch() throws IOException {
+
+ CandidateSpan xf = x.getMatchFirstSpan();
+ CandidateSpan xs = x.getMatchSecondSpan();
+
+ CandidateSpan yf = y.getMatchFirstSpan();
+ CandidateSpan ys = y.getMatchSecondSpan();
+
+ if (xf.getStart() == yf.getStart() &&
+ xf.getEnd() == yf.getEnd() &&
+ xs.getStart() == ys.getStart() &&
+ xs.getEnd() == ys.getEnd()){
+
+ matchStartPosition = x.start();
+ matchEndPosition = x.end();
+ matchDocNumber = x.doc();
+ matchPayload = x.matchPayload;
+
+ setMatchFirstSpan(x.getMatchFirstSpan());
+ setMatchSecondSpan(x.getMatchSecondSpan());
+ log.trace("doc# {}, start {}, end {}",matchDocNumber,
+ matchStartPosition,matchEndPosition);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean skipTo(int target) throws IOException {
+ if (hasMoreSpans && (y.doc() < target)){
+ if (!y.skipTo(target)){
+ return false;
+ }
+ }
+ matchPayload.clear();
+ isStartEnumeration=false;
+ return advance();
+ }
+
+ @Override
+ public long cost() {
+ return x.cost() + y.cost();
+ }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java
index 2c29093..3a03560 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java
@@ -29,7 +29,7 @@
protected List<CandidateSpan> firstSpanList, secondSpanList;
protected List<CandidateSpan> matchList;
private long matchCost;
- private int matchListSpanNum;
+ private int matchListSpanNum;
public UnorderedDistanceSpans(SpanDistanceQuery query,
AtomicReaderContext context, Bits acceptDocs,
@@ -49,10 +49,10 @@
}
@Override
- protected boolean advance() throws IOException {
+ protected boolean advance() throws IOException {
while (hasMoreSpans || !matchList.isEmpty()){
if (!matchList.isEmpty()){
- setMatchProperties();
+ setMatchProperties();
return true;
}
@@ -92,12 +92,13 @@
currentFirstSpan = firstSpanList.get(0) ;
currentSecondSpan = secondSpanList.get(0);
- if (currentFirstSpan.getEnd() <= currentSecondSpan.getEnd()){
+ if (currentFirstSpan.getEnd() < currentSecondSpan.getEnd() ||
+ isLastCandidateSmaller(currentFirstSpan, currentSecondSpan)){
matchList = findMatches(currentFirstSpan, secondSpanList);
setMatchFirstSpan(currentFirstSpan);
matchListSpanNum = 2;
updateList(firstSpanList);
- }
+ }
else {
matchList = findMatches(currentSecondSpan, firstSpanList);
setMatchSecondSpan(currentSecondSpan);
@@ -113,6 +114,17 @@
}
}
+ private boolean isLastCandidateSmaller(CandidateSpan currentFirstSpan, CandidateSpan
+ currentSecondSpan){
+ if (currentFirstSpan.getEnd() == currentSecondSpan.getEnd() ){
+ int secondEnd = secondSpanList.get(secondSpanList.size()-1).getEnd();
+ int firstEnd = firstSpanList.get(firstSpanList.size()-1).getEnd();
+ return (secondEnd < firstEnd ? true : false);
+ }
+
+ return false;
+ }
+
protected abstract void updateList(List<CandidateSpan> candidateList);
/** Set the candidate list for the first element in the target list.
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestMultipleDistanceIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestMultipleDistanceIndex.java
new file mode 100644
index 0000000..c7640cd
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/index/TestMultipleDistanceIndex.java
@@ -0,0 +1,270 @@
+package de.ids_mannheim.korap.index;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.spans.SpanQuery;
+import org.apache.lucene.search.spans.SpanTermQuery;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import de.ids_mannheim.korap.KorapIndex;
+import de.ids_mannheim.korap.KorapResult;
+import de.ids_mannheim.korap.query.DistanceConstraint;
+import de.ids_mannheim.korap.query.SpanElementQuery;
+import de.ids_mannheim.korap.query.SpanMultipleDistanceQuery;
+import de.ids_mannheim.korap.query.SpanNextQuery;
+
+@RunWith(JUnit4.class)
+public class TestMultipleDistanceIndex {
+
+ private KorapIndex ki;
+ private KorapResult kr;
+
+ public SpanQuery createQuery(String x, String y, List<DistanceConstraint>
+ constraints, boolean isOrdered){
+
+ SpanQuery sx = new SpanTermQuery(new Term("base",x));
+ SpanQuery sy = new SpanTermQuery(new Term("base",y));
+
+ return new SpanMultipleDistanceQuery(sx, sy, constraints, isOrdered, true);
+ }
+
+ public DistanceConstraint createConstraint(String unit, int min, int max){
+ if (unit.equals("w")){
+ return new DistanceConstraint(unit, min, max);
+ }
+ SpanQuery sq = new SpanElementQuery("base", unit);
+ return new DistanceConstraint(sq, unit, min, max);
+ }
+
+ private FieldDocument createFieldDoc0() {
+ FieldDocument fd = new FieldDocument();
+ fd.addString("ID", "doc-0");
+ fd.addTV("base",
+ "text",
+ "[(0-1)s:b|_1#0-1|<>:s#0-2$<i>2|<>:p#0-4$<i>4]" +
+ "[(1-2)s:b|s:c|_2#1-2]" +
+ "[(2-3)s:c|_3#2-3|<>:s#2-3$<i>4]" +
+ "[(3-4)s:b|_4#3-4]" +
+ "[(4-5)s:c|_5#4-5|<>:s#4-6$<i>6|<>:p#4-6$<i>6]" +
+ "[(5-6)s:e|_6#5-6]");
+ return fd;
+ }
+
+ private FieldDocument createFieldDoc1() {
+ FieldDocument fd = new FieldDocument();
+ fd.addString("ID", "doc-1");
+ fd.addTV("base",
+ "text",
+ "[(0-1)s:c|_1#0-1|<>:s#0-2$<i>2|<>:p#0-4$<i>4]" +
+ "[(1-2)s:c|s:e|_2#1-2]" +
+ "[(2-3)s:e|_3#2-3|<>:s#2-3$<i>4]" +
+ "[(3-4)s:c|_4#3-4]" +
+ "[(4-5)s:e|_5#4-5|<>:s#4-6$<i>6|<>:p#4-6$<i>6]" +
+ "[(5-6)s:c|_6#5-6]");
+ return fd;
+ }
+
+
+ private FieldDocument createFieldDoc2() {
+ FieldDocument fd = new FieldDocument();
+ fd.addString("ID", "doc-2");
+ fd.addTV("base",
+ "text",
+ "[(0-1)s:b|_1#0-1|<>:s#0-2$<i>2|<>:p#0-4$<i>4]" +
+ "[(1-2)s:b|s:e|_2#1-2]" +
+ "[(2-3)s:e|_3#2-3|<>:s#2-3$<i>4]" +
+ "[(3-4)s:b|s:c|_4#3-4]" +
+ "[(4-5)s:e|_5#4-5|<>:s#4-6$<i>6|<>:p#4-6$<i>6]" +
+ "[(5-6)s:d|_6#5-6]");
+ return fd;
+ }
+
+ private FieldDocument createFieldDoc3() {
+ FieldDocument fd = new FieldDocument();
+ fd.addString("ID", "doc-0");
+ fd.addTV("base",
+ "text",
+ "[(0-1)s:b|_1#0-1|<>:s#0-2$<i>2|<>:p#0-4$<i>4]" +
+ "[(1-2)s:b|s:c|_2#1-2]" +
+ "[(2-3)s:c|_3#2-3|<>:s#2-3$<i>4]" +
+ "[(3-4)s:b|_4#3-4]" +
+ "[(4-5)s:c|_5#4-5|<>:s#4-6$<i>6|<>:p#4-6$<i>6]" +
+ "[(5-6)s:d|_6#5-6]");
+ return fd;
+ }
+
+
+ /** Unordered, same sentence
+ * */
+ @Test
+ public void testCase1() throws IOException {
+ ki = new KorapIndex();
+ ki.addDoc(createFieldDoc0());
+ ki.commit();
+
+ List<DistanceConstraint> constraints = new ArrayList<DistanceConstraint>();
+ constraints.add(createConstraint("w", 0, 2));
+ constraints.add(createConstraint("s", 0, 0));
+
+ SpanQuery mdq;
+ mdq = createQuery("s:b", "s:c", constraints, false);
+ kr = ki.search(mdq, (short) 10);
+
+ assertEquals(3, kr.getTotalResults());
+ assertEquals(0, kr.getMatch(0).getStartPos());
+ assertEquals(2, kr.getMatch(0).getEndPos());
+ assertEquals(1, kr.getMatch(1).getStartPos());
+ assertEquals(2, kr.getMatch(1).getEndPos());
+ assertEquals(2, kr.getMatch(2).getStartPos());
+ assertEquals(4, kr.getMatch(2).getEndPos());
+ }
+
+ /** Ordered
+ * Unordered
+ * Two constraints
+ * Three constraints
+ * */
+ @Test
+ public void testCase2() throws IOException {
+ ki = new KorapIndex();
+ ki.addDoc(createFieldDoc0());
+ ki.commit();
+
+ List<DistanceConstraint> constraints = new ArrayList<DistanceConstraint>();
+ constraints.add(createConstraint("w", 0, 2));
+ constraints.add(createConstraint("s", 1, 1));
+
+ SpanQuery mdq;
+ // Ordered
+ mdq = createQuery("s:b", "s:c", constraints, true);
+ kr = ki.search(mdq, (short) 10);
+
+ assertEquals(3, kr.getTotalResults());
+ assertEquals(0, kr.getMatch(0).getStartPos());
+ assertEquals(3, kr.getMatch(0).getEndPos());
+ assertEquals(1, kr.getMatch(1).getStartPos());
+ assertEquals(3, kr.getMatch(1).getEndPos());
+ assertEquals(3, kr.getMatch(2).getStartPos());
+ assertEquals(5, kr.getMatch(2).getEndPos());
+
+ // Unordered
+ mdq = createQuery("s:c", "s:b", constraints, false);
+ kr = ki.search(mdq, (short) 10);
+ assertEquals(4, kr.getTotalResults());
+ assertEquals(1, kr.getMatch(2).getStartPos());
+ assertEquals(4, kr.getMatch(2).getEndPos());
+
+ // Three constraints
+ constraints.add(createConstraint("p", 0, 0));
+ mdq = createQuery("s:b", "s:c", constraints, true);
+ kr = ki.search(mdq, (short) 10);
+ assertEquals(2, kr.getTotalResults());
+
+ mdq = createQuery("s:b", "s:c", constraints, false);
+ kr = ki.search(mdq, (short) 10);
+ assertEquals(3, kr.getTotalResults());
+
+ }
+
+ /** Multiple documents
+ * Ensure same doc (inner term span)
+ * */
+ @Test
+ public void testCase3() throws IOException {
+ ki = new KorapIndex();
+ ki.addDoc(createFieldDoc0());
+ ki.addDoc(createFieldDoc1());
+ ki.addDoc(createFieldDoc2());
+ ki.commit();
+
+ List<DistanceConstraint> constraints = new ArrayList<DistanceConstraint>();
+ constraints.add(createConstraint("w", 1, 2));
+ constraints.add(createConstraint("s", 1, 2));
+
+ SpanQuery mdq;
+ mdq = createQuery("s:b", "s:e", constraints, false);
+ kr = ki.search(mdq, (short) 10);
+
+ assertEquals(3, kr.getTotalResults());
+ assertEquals(2, kr.getMatch(0).getLocalDocID());
+ assertEquals(0, kr.getMatch(0).getStartPos());
+ assertEquals(3, kr.getMatch(0).getEndPos());
+ assertEquals(1, kr.getMatch(1).getStartPos());
+ assertEquals(4, kr.getMatch(1).getEndPos());
+ assertEquals(3, kr.getMatch(2).getStartPos());
+ assertEquals(5, kr.getMatch(2).getEndPos());
+
+ }
+
+ /** Multiple documents
+ * Skip to
+ * */
+ @Test
+ public void testCase4() throws IOException {
+ ki = new KorapIndex();
+ ki.addDoc(createFieldDoc0());
+ ki.addDoc(createFieldDoc3());
+ ki.addDoc(createFieldDoc1());
+ ki.addDoc(createFieldDoc2());
+ ki.commit();
+
+ List<DistanceConstraint> constraints = new ArrayList<DistanceConstraint>();
+ constraints.add(createConstraint("w", 1, 2));
+ constraints.add(createConstraint("s", 1, 2));
+
+ SpanQuery mdq;
+ mdq = createQuery("s:b", "s:c", constraints, false);
+
+ SpanQuery sq = new SpanNextQuery(mdq,
+ new SpanTermQuery(new Term("base","s:e")));
+ kr = ki.search(sq, (short) 10);
+
+ assertEquals(2, kr.getTotalResults());
+ assertEquals(3, kr.getMatch(0).getStartPos());
+ assertEquals(6, kr.getMatch(0).getEndPos());
+ assertEquals(3, kr.getMatch(1).getLocalDocID());
+ assertEquals(1, kr.getMatch(1).getStartPos());
+ assertEquals(5, kr.getMatch(1).getEndPos());
+
+ }
+
+ /** Multiple documents
+ * Same tokens: ordered and unordered yield the same results
+ * */
+ @Test
+ public void testCase5() throws IOException {
+ ki = new KorapIndex();
+ ki.addDoc(createFieldDoc0());
+ ki.addDoc(createFieldDoc1());
+ ki.commit();
+
+ List<DistanceConstraint> constraints = new ArrayList<DistanceConstraint>();
+ constraints.add(createConstraint("w", 1, 2));
+ constraints.add(createConstraint("s", 1, 2));
+
+ SpanQuery mdq;
+ mdq = createQuery("s:c", "s:c", constraints, false);
+ kr = ki.search(mdq, (short) 10);
+
+ assertEquals(4, kr.getTotalResults());
+ assertEquals(1, kr.getMatch(0).getStartPos());
+ assertEquals(3, kr.getMatch(0).getEndPos());
+ assertEquals(2, kr.getMatch(1).getStartPos());
+ assertEquals(5, kr.getMatch(1).getEndPos());
+ assertEquals(1, kr.getMatch(2).getLocalDocID());
+ assertEquals(1, kr.getMatch(2).getStartPos());
+ assertEquals(4, kr.getMatch(2).getEndPos());
+ assertEquals(3, kr.getMatch(3).getStartPos());
+ assertEquals(6, kr.getMatch(3).getEndPos());
+
+ }
+
+}
+