Added temporary class mechanism for relation spans.
Includes 2 errors regarding snippet brackets / highlighting.
Change-Id: If993b6ab74bd9a61a64cc660bc8f29dd933e8714
diff --git a/src/main/java/de/ids_mannheim/korap/KrillQuery.java b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
index c966cc0..578d10b 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
@@ -85,10 +85,6 @@
private static final int MAX_CLASS_NUM = 255; // 127;
- // Variables used for relation queries
- private String direction;
- private byte[] classNumbers;
-
// Private class for koral:boundary objects
private class Boundary {
public int min, max;
@@ -121,7 +117,6 @@
};
};
-
/**
* Constructs a new object for query deserialization
* and building. Expects the name of an index field
@@ -133,10 +128,6 @@
*/
public KrillQuery (String field) {
this.field = field;
- this.direction = ">:";
- this.classNumbers = new byte[2];
- this.classNumbers[0] = (byte) 1;
- this.classNumbers[1] = (byte) 2;
};
@@ -257,9 +248,6 @@
if (number > MAX_CLASS_NUM)
throw new QueryException(709,
"Valid class numbers exceeded");
-
- this.classNumbers = null;
-
}
// Reference based on spans
@@ -303,12 +291,6 @@
// Get wrapped token
return this._segFromJson(json.get("wrap"));
- case "koral:relation":
- if (!json.has("wrap")) {
- throw new QueryException(718, "Missing relation term");
- }
- return this._termFromJson(json.get("wrap"), direction);
-
case "koral:span":
return this._termFromJson(json);
};
@@ -446,16 +428,28 @@
SpanQueryWrapper operand1 = fromJson(operands.get(0));
SpanQueryWrapper operand2 = fromJson(operands.get(1));
-
- if (operand1.isEmpty()) {
+
+ String direction = ">:";
+ if (operand1.isEmpty() && !operand2.isEmpty()) {
direction = "<:";
}
- SpanQueryWrapper relationWrapper = fromJson(relation);
-
- return new SpanRelationWrapper(relationWrapper, operand1, operand2,
- classNumbers);
-
+ if (!relation.has("@type"))
+ throw new QueryException(701,
+ "JSON-LD group has no @type attribute");
+
+ if (relation.get("@type").asText().equals("koral:relation")) {
+ if (!relation.has("wrap")) {
+ throw new QueryException(718, "Missing relation term");
+ }
+ SpanQueryWrapper relationWrapper = _termFromJson(
+ relation.get("wrap"),
+ direction);
+ return new SpanRelationWrapper(relationWrapper, operand1, operand2);
+ }
+ else {
+ throw new QueryException(713, "Query type is not supported");
+ }
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java b/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java
index ff47287..de1e4c8 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SimpleSpanQuery.java
@@ -72,9 +72,10 @@
protected SpanQuery firstClause = null, secondClause = null;
protected List<SpanQuery> clauseList = null;
- private String field;
+ protected String field;
protected boolean collectPayloads;
+ public SimpleSpanQuery () {}
/**
* Constructs a new SimpleSpanQuery using the specified
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanFocusQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanFocusQuery.java
index 305e42c..c144a58 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanFocusQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanFocusQuery.java
@@ -21,16 +21,13 @@
* Modify the span of a match to the boundaries of a certain class.
*
* In case multiple classes are found with the very same number, the
- * span is
- * maximized to start on the first occurrence from the left and end on
- * the last
- * occurrence on the right.
+ * span is maximized to start on the first occurrence from the left
+ * and end on the last occurrence on the right.
*
* In case the class to modify on is not found in the subquery, the
- * match is
- * ignored.
+ * match is ignored.
*
- * @author diewald
+ * @author diewald, margaretha
*
* @see FocusSpans
*/
@@ -38,7 +35,8 @@
private List<Byte> classNumbers = new ArrayList<Byte>();
private boolean isSorted = true;
-
+ private boolean matchTemporaryClass = false;
+ private boolean removeTemporaryClasses = false;
/**
* Construct a new SpanFocusQuery.
@@ -59,7 +57,6 @@
public SpanFocusQuery (SpanQuery sq, List<Byte> classNumbers) {
super(sq, true);
this.classNumbers = classNumbers;
- isSorted = false;
};
@@ -83,6 +80,9 @@
public String toString (String field) {
StringBuffer buffer = new StringBuffer();
buffer.append("focus(");
+ if (matchTemporaryClass){
+ buffer.append("#");
+ }
if (classNumbers.size() > 1) {
buffer.append("[");
for (int i = 0; i < classNumbers.size(); i++) {
@@ -133,6 +133,9 @@
SpanFocusQuery spanFocusQuery = new SpanFocusQuery(
(SpanQuery) this.firstClause.clone(), this.getClassNumbers());
spanFocusQuery.setBoost(getBoost());
+ spanFocusQuery.setMatchTemporaryClass(this.matchTemporaryClass);
+ spanFocusQuery.setSorted(this.isSorted);
+ spanFocusQuery.setRemoveTemporaryClasses(this.removeTemporaryClasses);
return spanFocusQuery;
};
@@ -185,4 +188,20 @@
this.isSorted = isSorted;
}
+ public boolean matchTemporaryClass() {
+ return matchTemporaryClass;
+ }
+
+ public void setMatchTemporaryClass(boolean matchTemporaryClass) {
+ this.matchTemporaryClass = matchTemporaryClass;
+ }
+
+ public boolean removeTemporaryClasses() {
+ return removeTemporaryClasses;
+ }
+
+ public void setRemoveTemporaryClasses(boolean rem) {
+ this.removeTemporaryClasses = rem;
+ }
+
};
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java
new file mode 100644
index 0000000..5bc962a
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java
@@ -0,0 +1,125 @@
+package de.ids_mannheim.korap.query;
+
+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.SpanQuery;
+import org.apache.lucene.search.spans.Spans;
+import org.apache.lucene.util.Bits;
+
+import de.ids_mannheim.korap.query.spans.FocusSpans;
+
+public class SpanRelationMatchQuery extends SimpleSpanQuery{
+
+ private SpanQuery operandQuery;
+ private SpanQuery operand2Query;
+ private SpanRelationQuery relationQuery;
+
+ public SpanRelationMatchQuery (SpanRelationQuery relation, SpanQuery operand,
+ boolean collectPayloads) {
+
+ checkVariables(relation, operand);
+ SpanFocusQuery sq = new SpanFocusQuery(new SpanSegmentQuery(
+ relationQuery, operandQuery, true),
+ relation.getTempClassNumbers());
+ sq.setMatchTemporaryClass(true);
+ sq.setRemoveTemporaryClasses(true);
+ sq.setSorted(false); // which operand to focus might be
+ // different from that to match
+
+ this.setFirstClause(sq);
+ this.collectPayloads = collectPayloads;
+ }
+
+ public SpanRelationMatchQuery (SpanRelationQuery relation, SpanQuery source,
+ SpanQuery target, boolean collectPayloads) {
+
+ checkVariables(relation, source, target);
+ SpanFocusQuery sq = null;
+ // match source
+ if (relationQuery.getDirection() == 0) {
+ sq = new SpanFocusQuery(new SpanSegmentQuery(relationQuery,
+ operandQuery, true), relation.getTempTargetNum());
+ }
+ // match target
+ else {
+ sq = new SpanFocusQuery(new SpanSegmentQuery(relationQuery,
+ operandQuery, true), relation.getTempSourceNum());
+ }
+ sq.setSorted(false);
+ sq.setMatchTemporaryClass(true);
+
+ SpanFocusQuery sq2 = new SpanFocusQuery(new SpanSegmentQuery(sq,
+ operand2Query, true), relation.getTempClassNumbers());
+ sq2.setMatchTemporaryClass(true);
+ sq2.setRemoveTemporaryClasses(true);
+ sq2.setSorted(false);
+
+ this.setFirstClause(sq2);
+ this.collectPayloads = collectPayloads;
+
+ }
+
+ public void checkVariables(SpanRelationQuery relation, SpanQuery operand) {
+ if (relation == null) {
+ throw new IllegalArgumentException(
+ "The relation query cannot be null.");
+ }
+ if (operand == null) {
+ throw new IllegalArgumentException(
+ "The operand query cannot be null.");
+ }
+ this.field = relation.getField();
+ if (!operand.getField().equals(field)) {
+ throw new IllegalArgumentException(
+ "Clauses must have the same field.");
+ }
+ this.relationQuery = relation;
+ this.operandQuery = operand;
+ }
+
+ public void checkVariables(SpanRelationQuery relation, SpanQuery operand, SpanQuery target) {
+ checkVariables(relation, operand);
+ if (target == null) {
+ if (operand == null) {
+ throw new IllegalArgumentException(
+ "The target query cannot be null.");
+ }
+ }
+ if (!target.getField().equals(field)) {
+ throw new IllegalArgumentException(
+ "Clauses must have the same field.");
+ }
+ this.operand2Query = target;
+ }
+
+ @Override
+ public SimpleSpanQuery clone() {
+ if (operand2Query != null) {
+ return new SpanRelationMatchQuery(
+ (SpanRelationQuery) relationQuery.clone(),
+ (SpanQuery) operandQuery.clone(),
+ (SpanQuery) operand2Query.clone(), collectPayloads);
+ }
+
+ return new SpanRelationMatchQuery(
+ (SpanRelationQuery) relationQuery.clone(),
+ (SpanQuery) operandQuery.clone(), collectPayloads);
+ }
+
+ @Override
+ public Spans getSpans(AtomicReaderContext context, Bits acceptDocs,
+ Map<Term, TermContext> termContexts) throws IOException {
+
+ return new FocusSpans((SpanFocusQuery) firstClause, context,
+ acceptDocs, termContexts);
+ }
+
+ @Override
+ public String toString(String field) {
+ return getFirstClause().toString();
+ }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanRelationQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanRelationQuery.java
index 8df29b3..8d06a7e 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanRelationQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanRelationQuery.java
@@ -1,6 +1,8 @@
package de.ids_mannheim.korap.query;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
import java.util.Map;
import org.apache.lucene.index.AtomicReaderContext;
@@ -55,7 +57,12 @@
public class SpanRelationQuery extends SimpleSpanQuery {
private int direction = 0;
+ private byte tempSourceNum = 1;
+ private byte tempTargetNum = 2;
+ private byte sourceClass;
+ private byte targetClass;
+ private List<Byte> tempClassNumbers = Arrays.asList(tempSourceNum, tempTargetNum);
/**
* Constructs a SpanRelationQuery based on the given span query.
*
@@ -76,6 +83,13 @@
}
}
+ public SpanRelationQuery (SpanQuery firstClause, List<Byte> classNumbers,
+ boolean collectPayloads) {
+ this(firstClause, collectPayloads);
+ this.tempClassNumbers = classNumbers;
+ this.tempSourceNum = classNumbers.get(0);
+ this.tempTargetNum = classNumbers.get(1);
+ }
@Override
public SimpleSpanQuery clone () {
@@ -95,9 +109,25 @@
@Override
public String toString (String field) {
StringBuilder sb = new StringBuilder();
+ if (sourceClass > 0) {
+ sb.append("{");
+ sb.append(sourceClass);
+ sb.append(": source:");
+ }
+ if (targetClass > 0) {
+ sb.append("{");
+ sb.append(targetClass);
+ sb.append(": target:");
+ }
sb.append("spanRelation(");
sb.append(firstClause.toString(field));
sb.append(")");
+ if (sourceClass > 0) {
+ sb.append("}");
+ }
+ if (targetClass > 0) {
+ sb.append("}");
+ }
sb.append(ToStringUtils.boost(getBoost()));
return sb.toString();
}
@@ -110,4 +140,54 @@
this.direction = direction;
}
+ public List<Byte> getTempClassNumbers() {
+ return tempClassNumbers;
+ }
+
+ public void setTempClassNumbers(List<Byte> classNumbers) {
+ this.tempClassNumbers = classNumbers;
+ }
+
+ public byte getTempSourceNum() {
+ return tempSourceNum;
+ }
+
+ public void setTempSourceNum(byte sourceNum) {
+ this.tempSourceNum = sourceNum;
+ }
+
+ public byte getTempTargetNum() {
+ return tempTargetNum;
+ }
+
+ public void setTempTargetNum(byte targetNum) {
+ this.tempTargetNum = targetNum;
+ }
+
+ public byte getSourceClass() {
+ return sourceClass;
+ }
+
+ public void setSourceClass(byte sourceClass)
+ throws IllegalArgumentException {
+ if (sourceClass < 1) {
+ throw new IllegalArgumentException(
+ "Class number must be bigger than 0.");
+ }
+
+ this.sourceClass = sourceClass;
+ }
+
+ public byte getTargetClass() {
+ return targetClass;
+ }
+
+ public void setTargetClass(byte targetClass)
+ throws IllegalArgumentException {
+ if (targetClass < 1) {
+ throw new IllegalArgumentException(
+ "Class number must be bigger than 0.");
+ }
+ this.targetClass = targetClass;
+ }
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanSegmentQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanSegmentQuery.java
index bb69d4c..7e75543 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanSegmentQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanSegmentQuery.java
@@ -46,7 +46,6 @@
this(firstClause, secondClause, true);
}
-
/**
* Constructs a SpanSegmentQuery from the two given SpanQueries.
*
@@ -61,16 +60,11 @@
* <code>false</code>.
*/
public SpanSegmentQuery (SpanQuery firstClause, SpanQuery secondClause,
- boolean collectPayloads) {
+ boolean collectPayloads) {
super(firstClause, secondClause, collectPayloads);
- }
-
-
- public SpanSegmentQuery (SpanRelationQuery firstClause,
- SimpleSpanQuery secondClause,
- boolean collectPayloads) {
- super(firstClause, secondClause, true);
- isRelation = true;
+ if (firstClause instanceof SpanRelationQuery) {
+ isRelation = true;
+ }
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/ClassSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/ClassSpans.java
index 4e97dbc..ac83c4d 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/ClassSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/ClassSpans.java
@@ -26,16 +26,16 @@
* @author diewald
*/
-public class ClassSpans extends Spans {
- private List<byte[]> classedPayload;
- private final Spans spans;
- private byte number;
- private SpanQuery operand;
- private Boolean hasmorespans = false;
+public class ClassSpans extends SimpleSpans {
+ protected List<byte[]> classedPayload;
+ protected Spans spans;
+ protected byte number;
+ protected SpanQuery operand;
+ protected Boolean hasmorespans = false;
- private ByteBuffer bb = ByteBuffer.allocate(9);
+ protected ByteBuffer bb;
- private final static Logger log = LoggerFactory.getLogger(ClassSpans.class);
+ private final Logger log = LoggerFactory.getLogger(ClassSpans.class);
// This advices the java compiler to ignore all loggings
public static final boolean DEBUG = false;
@@ -69,6 +69,8 @@
// The highlighted payload
this.classedPayload = new ArrayList<byte[]>(3);
+
+ this.bb = ByteBuffer.allocate(9);
};
@@ -126,7 +128,7 @@
};
- private boolean addClassPayload () throws IOException {
+ protected boolean addClassPayload() throws IOException {
hasmorespans = true;
classedPayload.clear();
@@ -149,6 +151,12 @@
// Add highlight information as byte array
classedPayload.add(bb.array());
+
+ if (spans instanceof SimpleSpans) {
+ SimpleSpans ss = (SimpleSpans) spans;
+ this.hasSpanId = ss.hasSpanId;
+ this.spanId = ss.spanId;
+ }
return true;
};
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
index 2da1558..ae3fe59 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
@@ -52,12 +52,10 @@
// This advices the java compiler to ignore all loggings
public static final boolean DEBUG = false;
- // private SimpleSpans originalSpans;
- private boolean isSorted;
+ private boolean isSorted, matchTemporaryClass, removeTemporaryClasses;
private List<CandidateSpan> candidateSpans;
private int windowSize = 10;
private int currentDoc;
- private byte number;
/**
@@ -86,13 +84,16 @@
}
classNumbers = query.getClassNumbers();
isSorted = query.isSorted();
+ matchTemporaryClass = query.matchTemporaryClass();
+ removeTemporaryClasses = query.removeTemporaryClasses();
candidateSpans = new ArrayList<CandidateSpan>();
hasMoreSpans = firstSpans.next();
currentDoc = firstSpans.doc();
- // matchPayload = new ArrayList<byte[]>(6);
this.query = query;
- hasSpanId = true;
+ if (getSpanId() > 0) {
+ hasSpanId = true;
+ }
}
@@ -164,7 +165,8 @@
for (byte[] payload : firstSpans.getPayload()) {
// No class payload - ignore
// this may be problematic for other calculated payloads!
- if (payload.length == 9) {
+ if ((!matchTemporaryClass && payload.length == 9)
+ || (matchTemporaryClass && payload.length == 10)) {
if (classNumbers.contains(payload[8])) {
isClassFound = true;
classStart = byte2int(payload, 0);
@@ -178,9 +180,12 @@
maxPos = classEnd;
}
}
- candidateSpan.getPayloads().add(payload.clone());
}
+ if (removeTemporaryClasses && payload.length == 10) {
+ continue;
+ }
+ candidateSpan.getPayloads().add(payload.clone());
}
if (isClassFound) {
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/RelationSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/RelationSpans.java
index f17043d..66afdbe 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/RelationSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/RelationSpans.java
@@ -58,7 +58,8 @@
protected Logger logger = LoggerFactory.getLogger(RelationSpans.class);
private List<CandidateRelationSpan> candidateList;
-
+ private byte tempSourceNum, tempTargetNum;
+ private byte sourceClass, targetClass;
/**
* Constructs RelationSpans from the given
@@ -77,6 +78,11 @@
throws IOException {
super(relationSpanQuery, context, acceptDocs, termContexts);
direction = relationSpanQuery.getDirection();
+ tempSourceNum = relationSpanQuery.getTempSourceNum();
+ tempTargetNum = relationSpanQuery.getTempTargetNum();
+ sourceClass = relationSpanQuery.getSourceClass();
+ targetClass = relationSpanQuery.getTargetClass();
+
candidateList = new ArrayList<>();
relationTermSpan = (TermSpans) firstSpans;
hasMoreSpans = relationTermSpan.next();
@@ -213,22 +219,47 @@
}
if (direction == 0) {
payload.add(createClassPayload(cs.getLeftStart(), cs.getLeftEnd(),
- (byte) 1));
+ tempSourceNum, false));
payload.add(createClassPayload(cs.getRightStart(),
- cs.getRightEnd(), (byte) 2));
+ cs.getRightEnd(), tempTargetNum, false));
+
+ if (sourceClass > 0) {
+ payload.add(createClassPayload(cs.getLeftStart(),
+ cs.getLeftEnd(), sourceClass, true));
+ }
+ if (targetClass > 0) {
+ payload.add(createClassPayload(cs.getRightStart(),
+ cs.getRightEnd(), targetClass, true));
+ }
+
}
else {
payload.add(createClassPayload(cs.getRightStart(),
- cs.getRightEnd(), (byte) 1));
+ cs.getRightEnd(), tempSourceNum, false));
payload.add(createClassPayload(cs.getLeftStart(), cs.getLeftEnd(),
- (byte) 2));
+ tempTargetNum, false));
+
+ if (sourceClass > 0) {
+ payload.add(createClassPayload(cs.getRightStart(),
+ cs.getRightEnd(), sourceClass, true));
+ }
+ if (targetClass > 0) {
+ payload.add(createClassPayload(cs.getLeftStart(),
+ cs.getLeftEnd(), targetClass, true));
+ }
}
cs.setPayloads(payload);
}
-
- private byte[] createClassPayload (int start, int end, byte classNumber) {
- ByteBuffer buffer = ByteBuffer.allocate(9);
+ private byte[] createClassPayload(int start, int end, byte classNumber,
+ boolean keep) {
+ ByteBuffer buffer = null;
+ if (keep) {
+ buffer = ByteBuffer.allocate(9);
+ }
+ else {
+ buffer = ByteBuffer.allocate(10);
+ }
buffer.putInt(start);
buffer.putInt(end);
buffer.put(classNumber);
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java
index 8ac53b8..9d40d31 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java
@@ -94,6 +94,7 @@
protected int findMatch () {
RelationSpans s1;
SimpleSpans s2;
+
if (firstSpans.start() == secondSpans.start()
&& firstSpans.end() == secondSpans.end()) {
@@ -101,13 +102,18 @@
s1 = (RelationSpans) firstSpans;
s2 = (SimpleSpans) secondSpans;
- //System.out.println("segment: " + s1.getRightStart() + " "
- // + s1.getRightEnd());
- if (s1.getLeftId() == s2.getSpanId()) {
+ if (s2.hasSpanId) {
+ if (s1.getLeftId() == s2.getSpanId()) {
+ setSpanId(s2.getSpanId());
+ setMatch();
+ return 0;
+ }
+ }
+ else {
setMatch();
- setSpanId(s2.getSpanId());
return 0;
}
+
}
else {
setMatch();
diff --git a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanRelationWrapper.java b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanRelationWrapper.java
index 17afa22..2535ce9 100644
--- a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanRelationWrapper.java
+++ b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanRelationWrapper.java
@@ -1,11 +1,11 @@
package de.ids_mannheim.korap.query.wrap;
-import java.util.ArrayList;
-
import org.apache.lucene.search.spans.SpanQuery;
+import org.apache.lucene.search.spans.SpanTermQuery;
import de.ids_mannheim.korap.query.SpanFocusQuery;
-import de.ids_mannheim.korap.query.SpanSegmentQuery;
+import de.ids_mannheim.korap.query.SpanRelationMatchQuery;
+import de.ids_mannheim.korap.query.SpanRelationQuery;
import de.ids_mannheim.korap.util.QueryException;
public class SpanRelationWrapper extends SpanQueryWrapper {
@@ -13,12 +13,9 @@
private SpanQueryWrapper relationQuery;
private SpanQueryWrapper subQuery1;
private SpanQueryWrapper subQuery2;
- private byte[] classNumbers;
-
public SpanRelationWrapper (SpanQueryWrapper relationWrapper,
- SpanQueryWrapper operand1,
- SpanQueryWrapper operand2, byte[] classNumbers) {
+ SpanQueryWrapper operand1, SpanQueryWrapper operand2) {
this.relationQuery = relationWrapper;
if (relationQuery != null) {
@@ -34,70 +31,63 @@
this.subQuery1 = operand1;
this.subQuery2 = operand2;
- this.classNumbers = classNumbers;
}
@Override
- public SpanQuery toQuery () throws QueryException {
+ public SpanQuery toQuery() throws QueryException {
if (this.isNull() || this.isEmpty()) {
return null;
}
- SpanQuery sq = relationQuery.retrieveNode(this.retrieveNode).toQuery();
- if (sq == null)
+ SpanTermQuery relationTermQuery = (SpanTermQuery) relationQuery.retrieveNode(
+ this.retrieveNode).toQuery();
+ if (relationTermQuery == null)
return null;
-
+
+ SpanRelationQuery rq = new SpanRelationQuery(relationTermQuery, true);
SpanQuery subq1, subq2;
+
if (subQuery1.isEmpty) {
if (!subQuery2.isEmpty) {
// match target
subq2 = subQuery2.retrieveNode(this.retrieveNode).toQuery();
- if (subq2 != null) {
- return createQuery(new SpanSegmentQuery(sq, subq2, true));
+ if (subQuery1.hasClass) {
+ rq.setSourceClass(subQuery1.getClassNumber());
}
+
+ return new SpanRelationMatchQuery(rq, subq2, true);
}
}
else if (subQuery2.isEmpty) {
if (!subQuery1.isEmpty) {
// match source
subq1 = subQuery1.retrieveNode(this.retrieveNode).toQuery();
- if (subq1 != null) {
- return createQuery(new SpanSegmentQuery(sq, subq1, true));
+ if (subQuery2.hasClass) {
+ rq.setTargetClass(subQuery2.getClassNumber());
}
+ return new SpanRelationMatchQuery(rq, subq1, true);
}
}
else {
// match both
subq1 = subQuery1.retrieveNode(this.retrieveNode).toQuery();
- if (subq1 != null) {
- SpanFocusQuery fq = new SpanFocusQuery(new SpanSegmentQuery(sq,
- subq1, true), (byte) 2);
- fq.setSorted(false);
- sq = fq;
- }
-
subq2 = subQuery2.retrieveNode(this.retrieveNode).toQuery();
- if (subq2 != null) {
- return createQuery(new SpanSegmentQuery(sq, subq2, true));
- }
+ return new SpanRelationMatchQuery(rq, subq1, subq2, true);
}
- return createQuery(sq);
- }
-
- private SpanQuery createQuery(SpanQuery sq) {
- ArrayList<Byte> classNumbers = new ArrayList<Byte>();
- if (this.classNumbers != null) {
- for (byte c : this.classNumbers) {
- if (c > 0) {
- classNumbers.add(c);
- }
- }
- return new SpanFocusQuery(sq, classNumbers);
+ // both empty
+ if (subQuery1.hasClass) {
+ rq.setSourceClass(subQuery1.getClassNumber());
}
- return sq;
-
+ if (subQuery2.hasClass) {
+ rq.setTargetClass(subQuery2.getClassNumber());
+ }
+ SpanFocusQuery fq = new SpanFocusQuery(rq, rq.getTempClassNumbers());
+ fq.setMatchTemporaryClass(true);
+ fq.setRemoveTemporaryClasses(true);
+ fq.setSorted(false);
+ return fq;
}
}
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
index e0d6598..a183fe8 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
@@ -3,7 +3,6 @@
import static org.junit.Assert.assertEquals;
import java.io.IOException;
-import java.util.ArrayList;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.spans.SpanQuery;
@@ -12,8 +11,10 @@
import de.ids_mannheim.korap.KrillIndex;
import de.ids_mannheim.korap.query.SpanAttributeQuery;
+import de.ids_mannheim.korap.query.SpanClassQuery;
import de.ids_mannheim.korap.query.SpanElementQuery;
import de.ids_mannheim.korap.query.SpanFocusQuery;
+import de.ids_mannheim.korap.query.SpanRelationMatchQuery;
import de.ids_mannheim.korap.query.SpanRelationQuery;
import de.ids_mannheim.korap.query.SpanSegmentQuery;
import de.ids_mannheim.korap.query.SpanTermWithIdQuery;
@@ -128,7 +129,7 @@
+ "<:child-of$<i>0<s>3<s>3<s>1|"
+ "<:child-of$<i>7<i>0<i>1<s>4<s>2<s>3|"
+ "<:child-of$<i>7<i>1<i>7<s>5<s>2<s>2|"
- + "<:dep$<i>1<s>2<s>1<s>1|"
+ + "<:dep$<i>0<s>2<s>1<s>1|"
+ "r@:func=sbj$<i>0<i>7<s>1]"
+
@@ -149,14 +150,15 @@
+ "<:child-of$<i>4<b>0<i>3<s>14<s>3<s>1|"
+ "<:child-of$<i>7<i>2<i>4<s>15<s>4<s>3|"
+ "<:child-of$<i>7<i>4<i>7<s>16<s>4<s>2|"
- + "<:dep$<i>3<s>2<s>1<s>1]" +
+ + ">:parent-of$<i>7<i>4<i>7<s>17<s>4<s>2|"
+ + "<:dep$<i>3<s>3<s>1<s>1]" +
"[(3-4)s:Blümen|_3#14-20|pos:NN$<s>1|"
+ ">:child-of$<i>2<i>4<s>17<s>1<s>3|"
+ "<:dep$<i>1<s>2<s>1<s>1|" + ">:dep$<i>2<s>3<s>1<s>1|"
+ ">:dep$<i>4<s>4<s>1<s>1|"
- + "r@:func=head$<i>2<i>4<s>2|"
- + "r@:func=obj$<i>1<i>4<s>2]" +
+ + "r@:func=head$<i>2<i>4<s>3|"
+ + "r@:func=obj$<i>2<i>4<s>3]" +
"[(4-5)s:für|_4#21-24|pos:PREP$<s>1|<>:pp#21-38$<i>7<s>2|"
+ ">:child-of$<i>4<i>7<s>18<s>1<s>2|"
@@ -261,9 +263,7 @@
/**
- * Relations with attributes
- * need focusMulti on span relation query before
- * SpanWithAttributeQuery
+ * Relations only
* */
@Test
public void testCase3 () throws IOException {
@@ -288,32 +288,11 @@
assertEquals(3, kr.getMatch(4).getEndPos());
assertEquals(2, kr.getMatch(5).getStartPos());
assertEquals(4, kr.getMatch(5).getEndPos());
-
- ArrayList<Byte> classNumbers = new ArrayList<Byte>();
- classNumbers.add((byte) 1);
- classNumbers.add((byte) 2);
-
- SpanFocusQuery fq = new SpanFocusQuery(srq, classNumbers);
- kr = ki.search(fq, (short) 20);
- /*
- * for (Match km : kr.getMatches()) {
- * System.out.println(km.getStartPos() + "," + km.getEndPos()
- * + " " + km.getSnippetBrackets()); }
- */
- assertEquals((long) 13, kr.getTotalResults());
- assertEquals(0, kr.getMatch(0).getStartPos());
- assertEquals(1, kr.getMatch(0).getEndPos());
- assertEquals(0, kr.getMatch(1).getStartPos());
- assertEquals(7, kr.getMatch(1).getEndPos());
- assertEquals(0, kr.getMatch(2).getStartPos());
- assertEquals(7, kr.getMatch(2).getEndPos());
- assertEquals(1, kr.getMatch(3).getStartPos());
- assertEquals(7, kr.getMatch(3).getEndPos());
- assertEquals(1, kr.getMatch(4).getStartPos());
- assertEquals(7, kr.getMatch(4).getEndPos());
}
-
+ /**
+ * Relations only with/out attribute
+ * */
@Test
public void testCase4 () throws IOException {
ki.addDoc(createFieldDoc2());
@@ -322,12 +301,14 @@
SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
new Term("base", ">:child-of")), true);
- ArrayList<Byte> classNumbers = new ArrayList<Byte>();
- classNumbers.add((byte) 1);
- classNumbers.add((byte) 2);
+ SpanFocusQuery fq = new SpanFocusQuery(srq, srq.getTempClassNumbers());
+ fq.setMatchTemporaryClass(true);
+ fq.setRemoveTemporaryClasses(true);
+ fq.setSorted(false);
- SpanWithAttributeQuery wq = new SpanWithAttributeQuery(
- new SpanFocusQuery(srq, classNumbers), new SpanAttributeQuery(
+ // child-of with attr func=sbj
+ SpanWithAttributeQuery wq = new SpanWithAttributeQuery(fq,
+ new SpanAttributeQuery(
new SpanTermQuery(new Term("base", "r@:func=sbj")),
true), true);
@@ -337,7 +318,7 @@
assertEquals(7, kr.getMatch(0).getEndPos());
// child-of without attr func=sbj
- wq = new SpanWithAttributeQuery(new SpanFocusQuery(srq, classNumbers),
+ wq = new SpanWithAttributeQuery(fq,
new SpanAttributeQuery(new SpanTermQuery(new Term("base",
"r@:func=sbj")), true, true), true);
kr = ki.search(wq, (short) 20);
@@ -345,87 +326,9 @@
}
- @Test
- public void testCase5 () throws IOException {
-
- ki.addDoc(createFieldDoc2());
- ki.commit();
-
- SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
- new Term("base", "<:dep")), true);
- kr = ki.search(srq, (short) 10);
-
- ArrayList<Byte> classNumbers = new ArrayList<Byte>();
- classNumbers.add((byte) 1);
- classNumbers.add((byte) 2);
-
- SpanFocusQuery fq = new SpanFocusQuery(srq, classNumbers);
- kr = ki.search(fq, (short) 10);
- // for (Match km : kr.getMatches()) {
- // System.out.println(km.getStartPos() + "," + km.getEndPos()
- // + " "
- // + km.getSnippetBrackets());
- // }
-
- SpanAttributeQuery saq = new SpanAttributeQuery(new SpanTermQuery(
- new Term("base", "r@:func=obj")), true);
- kr = ki.search(saq, (short) 10);
-
- // child-of with attr func-obj
- SpanWithAttributeQuery wq = new SpanWithAttributeQuery(
- new SpanFocusQuery(srq, classNumbers), new SpanAttributeQuery(
- new SpanTermQuery(new Term("base", "r@:func=obj")),
- true), true);
-
- kr = ki.search(wq, (short) 10);
- assertEquals((long) 1, kr.getTotalResults());
- assertEquals(1, kr.getMatch(0).getStartPos()); // element
- assertEquals(4, kr.getMatch(0).getEndPos());
- }
-
-
- @Test
- public void testCase10 () throws IOException {
- ki.addDoc(createFieldDoc2());
- ki.commit();
- // target of a dependency relation
- SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
- new Term("base", "<:dep")), true);
- kr = ki.search(srq, (short) 10);
- assertEquals((long) 6, kr.getTotalResults());
-
- ArrayList<Byte> classNumbers = new ArrayList<Byte>();
- classNumbers.add((byte) 1);
- classNumbers.add((byte) 2);
-
- SpanFocusQuery fq = new SpanFocusQuery(srq, classNumbers);
- kr = ki.search(fq, (short) 10);
- assertEquals((long) 6, kr.getTotalResults());
-
- SpanAttributeQuery aq = new SpanAttributeQuery(new SpanTermQuery(
- new Term("base", "r@:func=head")), true);
- kr = ki.search(aq, (short) 10);
-
- // dependency relation, which is also a head
- SpanWithAttributeQuery wq = new SpanWithAttributeQuery(
- new SpanFocusQuery(srq, classNumbers), new SpanAttributeQuery(
- new SpanTermQuery(new Term("base", "r@:func=head")),
- true), true);
-
- kr = ki.search(wq, (short) 20);
-
- assertEquals((long) 2, kr.getTotalResults());
- assertEquals(2, kr.getMatch(0).getStartPos());
- assertEquals(4, kr.getMatch(0).getEndPos());
- assertEquals(5, kr.getMatch(1).getStartPos());
- assertEquals(7, kr.getMatch(1).getEndPos());
-
- }
-
-
/**
- * Match left return left
- * Match right return right
+ * Relation directions <br/>
+ * Relation with specific sources, return the sources
* */
@Test
public void testCase6 () throws IOException {
@@ -433,9 +336,15 @@
ki.commit();
// return all children that are NP
- SpanQuery rv = new SpanSegmentQuery(new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:child-of")), true),
- new SpanElementQuery("base", "np"), true);
+ SpanElementQuery seq1 = new SpanElementQuery("base", "np");
+ SpanClassQuery scq1 = new SpanClassQuery(seq1, (byte) 1);
+
+ SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+ new Term("base", ">:child-of")), true);
+
+ SpanRelationMatchQuery rm = new SpanRelationMatchQuery(srq, scq1, true);
+ SpanFocusQuery rv = new SpanFocusQuery(rm, (byte) 1);
+ rv.setSorted(false);
kr = ki.search(rv, (short) 10);
@@ -450,10 +359,10 @@
assertEquals(7, kr.getMatch(3).getEndPos());
// return all parents that are NP
- rv = new SpanSegmentQuery(new SpanRelationQuery(new SpanTermQuery(
- new Term("base", "<:child-of")), true), new SpanElementQuery(
- "base", "np"), true);
-
+ srq = new SpanRelationQuery(new SpanTermQuery(new Term("base",
+ "<:child-of")), true);
+ rm = new SpanRelationMatchQuery(srq, scq1, true);
+ rv = new SpanFocusQuery(rm, (byte) 1);
kr = ki.search(rv, (short) 10);
assertEquals(7, kr.getTotalResults());
@@ -473,10 +382,53 @@
assertEquals(7, kr.getMatch(6).getEndPos());
}
+ /**
+ * Dependency relations with attribute
+ * */
+ @Test
+ public void testCase5() throws IOException {
+ ki.addDoc(createFieldDoc2());
+ ki.commit();
+
+ // target of a dependency relation
+ SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+ new Term("base", "<:dep")), true);
+ kr = ki.search(srq, (short) 10);
+ assertEquals((long) 6, kr.getTotalResults());
+
+ SpanFocusQuery fq = new SpanFocusQuery(srq, srq.getTempClassNumbers());
+ fq.setMatchTemporaryClass(true);
+ fq.setRemoveTemporaryClasses(true);
+ // fq.setSorted(false);
+
+ kr = ki.search(fq, (short) 10);
+ assertEquals((long) 6, kr.getTotalResults());
+ // for (Match km : kr.getMatches()) {
+ // System.out.println(km.getStartPos() + "," + km.getEndPos()
+ // + " "
+ // + km.getSnippetBrackets());
+ // }
+ SpanAttributeQuery aq = new SpanAttributeQuery(new SpanTermQuery(
+ new Term("base", "r@:func=head")), true);
+ kr = ki.search(aq, (short) 10);
+
+ // dependency relation, which is also a head
+ SpanWithAttributeQuery wq = new SpanWithAttributeQuery(fq,
+ new SpanAttributeQuery(new SpanTermQuery(new Term("base",
+ "r@:func=head")), true), true);
+
+ kr = ki.search(wq, (short) 20);
+
+ assertEquals((long) 2, kr.getTotalResults());
+ assertEquals(2, kr.getMatch(0).getStartPos());
+ assertEquals(4, kr.getMatch(0).getEndPos());
+ assertEquals(5, kr.getMatch(1).getStartPos());
+ assertEquals(7, kr.getMatch(1).getEndPos());
+
+ }
/**
- * Match left, return right
- * sort by left, then sort by right
+ * Relation with specific targets, return any sources
* */
@Test
public void testCase7 () throws IOException {
@@ -484,9 +436,17 @@
ki.commit();
// return all children that are NP
- SpanQuery rv = new SpanSegmentQuery(new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:child-of")), true),
- new SpanElementQuery("base", "np"), true);
+
+ SpanElementQuery seq1 = new SpanElementQuery("base", "np");
+ SpanClassQuery scq1 = new SpanClassQuery(seq1, (byte) 1);
+
+ SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+ new Term("base", ">:child-of")), true);
+ srq.setTargetClass((byte) 2);
+
+ SpanRelationMatchQuery rm = new SpanRelationMatchQuery(srq, scq1, true);
+ SpanQuery rv = new SpanFocusQuery(rm, (byte) 1);
+
//return all parents of np
SpanFocusQuery rv2 = new SpanFocusQuery(rv, (byte) 2);
@@ -519,26 +479,32 @@
ki.commit();
//return source of dep relations to pos:NN
- SpanQuery rv = new SpanFocusQuery(new SpanSegmentQuery(
- new SpanRelationQuery(new SpanTermQuery(new Term("base",
- "<:dep")), true), new SpanTermWithIdQuery(new Term(
- "base", "pos:NN"), true), true), (byte) 1);
+
+ SpanTermWithIdQuery tq = new SpanTermWithIdQuery(new Term("base",
+ "pos:NN"), true);
+ SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(new Term("base",
+ "<:dep")), true);
+ srq.setSourceClass((byte) 1);
+ SpanRelationMatchQuery rm = new SpanRelationMatchQuery(srq, tq, true);
+ SpanQuery rv = new SpanFocusQuery(rm, (byte) 1);
kr = ki.search(rv, (short) 10);
assertEquals((long) 3, kr.getTotalResults());
- assertEquals(1, kr.getMatch(0).getStartPos());
- assertEquals(2, kr.getMatch(0).getEndPos());
+ assertEquals(0, kr.getMatch(0).getStartPos());
+ assertEquals(1, kr.getMatch(0).getEndPos());
assertEquals(1, kr.getMatch(1).getStartPos());
assertEquals(2, kr.getMatch(1).getEndPos());
assertEquals(4, kr.getMatch(2).getStartPos());
assertEquals(5, kr.getMatch(2).getEndPos());
- //return target of dep relations from pos:NN
- rv = new SpanFocusQuery(
- new SpanSegmentQuery(new SpanRelationQuery(new SpanTermQuery(
- new Term("base", ">:dep")), true),
- new SpanTermWithIdQuery(new Term("base", "pos:NN"),
- true), true), (byte) 2);
+ // return target of dep relations from pos:NN
+ srq = new SpanRelationQuery(
+ new SpanTermQuery(
+ new Term("base", ">:dep")), true);
+ srq.setTargetClass((byte) 1);
+ rm = new SpanRelationMatchQuery(srq, tq, true);
+ rv = new SpanFocusQuery(rm, (byte) 1);
+
kr = ki.search(rv, (short) 10);
assertEquals((long) 3, kr.getTotalResults());
assertEquals(2, kr.getMatch(0).getStartPos());
@@ -552,8 +518,9 @@
/**
- * Relation with variable match right, return left sort by right,
- * then sort by left
+ * Relation with specific sources and return any targets <br/>
+ * Relation with specific sources and targets, return the targets <br/>
+ * Relation with specific sources and targets, return the sources
*
* @throws IOException
* */
@@ -563,10 +530,14 @@
ki.commit();
// return all children of np
- SpanFocusQuery rv = new SpanFocusQuery(new SpanSegmentQuery(
- new SpanRelationQuery(new SpanTermQuery(new Term("base",
- "<:child-of")), true), new SpanElementQuery("base",
- "np"), true), (byte) 1);
+ SpanElementQuery seq1 = new SpanElementQuery("base", "np");
+ SpanClassQuery scq1 = new SpanClassQuery(seq1, (byte) 1);
+ SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+ new Term("base", "<:child-of")), true);
+ srq.setSourceClass((byte) 2);
+ SpanRelationMatchQuery rm = new SpanRelationMatchQuery(srq, scq1, true);
+ SpanFocusQuery rv = new SpanFocusQuery(rm, (byte) 2);
+
rv.setSorted(false);
kr = ki.search(rv, (short) 10);
@@ -586,12 +557,19 @@
assertEquals(6, kr.getMatch(5).getEndPos());
assertEquals(6, kr.getMatch(6).getStartPos());
assertEquals(7, kr.getMatch(6).getEndPos());
- // sorting left problem (solved)
// return all children of np that are articles
- SpanSegmentQuery rv2 = new SpanSegmentQuery(rv, new SpanTermQuery(
- new Term("base", "pos:ART")));
- kr = ki.search(rv2, (short) 10);
+
+ SpanTermWithIdQuery tiq = new SpanTermWithIdQuery(new Term("base",
+ "pos:ART"), true);
+ SpanClassQuery scq2 = new SpanClassQuery(tiq, (byte) 2);
+
+ srq = new SpanRelationQuery(new SpanTermQuery(new Term("base",
+ ">:child-of")), true);
+ rm = new SpanRelationMatchQuery(srq, scq2, scq1, true);
+ rv = new SpanFocusQuery(rm, (byte) 2);
+
+ kr = ki.search(rv, (short) 10);
assertEquals((long) 2, kr.getTotalResults());
assertEquals(2, kr.getMatch(0).getStartPos());
@@ -603,17 +581,41 @@
SpanSegmentQuery rv3 = new SpanSegmentQuery(rv,
new SpanTermWithIdQuery(new Term("base", "pos:ART"), true));
-
SpanFocusQuery sf = new SpanFocusQuery(rv3, (byte) 1);
kr = ki.search(sf, (short) 10);
assertEquals((long) 2, kr.getTotalResults());
-
assertEquals(2, kr.getMatch(0).getStartPos());
- assertEquals(3, kr.getMatch(0).getEndPos());
+ assertEquals(4, kr.getMatch(0).getEndPos());
assertEquals(5, kr.getMatch(1).getStartPos());
- assertEquals(6, kr.getMatch(1).getEndPos());
+ assertEquals(7, kr.getMatch(1).getEndPos());
}
+ @Test
+ public void testCase10() throws IOException {
+ ki.addDoc(createFieldDoc2());
+ ki.commit();
+ SpanElementQuery seq1 = new SpanElementQuery("base", "np");
+ SpanElementQuery seq2 = new SpanElementQuery("base", "np");
+ SpanClassQuery scq1 = new SpanClassQuery(seq1, (byte) 1);
+ SpanClassQuery scq2 = new SpanClassQuery(seq2, (byte) 2);
+
+ SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+ new Term("base", ">:child-of")), true);
+ SpanRelationMatchQuery rq = new SpanRelationMatchQuery(srq, scq2, true);
+
+ kr = ki.search(rq, (short) 10);
+
+ assertEquals((long) 4, kr.getTotalResults());
+ assertEquals(0, kr.getMatch(0).getStartPos());
+ assertEquals(7, kr.getMatch(0).getEndPos());
+ assertEquals(1, kr.getMatch(1).getStartPos());
+ assertEquals(7, kr.getMatch(1).getEndPos());
+ assertEquals(2, kr.getMatch(2).getStartPos());
+ assertEquals(7, kr.getMatch(2).getEndPos());
+ assertEquals(4, kr.getMatch(3).getStartPos());
+ assertEquals(7, kr.getMatch(3).getEndPos());
+ }
+
}
\ No newline at end of file
diff --git a/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java b/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java
index 2512d1d..fccd34a 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java
@@ -19,7 +19,7 @@
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus([1,2]spanSegment(tokens:>:mate/d:HEAD, <tokens:c:s />))",
+ "focus(#[1,2]spanSegment(spanRelation(tokens:>:mate/d:HEAD), <tokens:c:s />))",
sq.toString());
}
@@ -32,7 +32,7 @@
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus([1,2]spanSegment(tokens:<:mate/d:HEAD, <tokens:c:vp />))",
+ "focus(#[1,2]spanSegment(spanRelation(tokens:<:mate/d:HEAD), <tokens:c:vp />))",
sq.toString());
}
@@ -45,7 +45,7 @@
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus([1,2]spanSegment(focus(2: spanSegment(tokens:>:mate/d:HEAD, <tokens:c:s />)), <tokens:c:vp />))",
+ "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), <tokens:c:s />)), <tokens:c:vp />))",
sq.toString());
}
@@ -58,7 +58,7 @@
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus([1,2]spanSegment(focus(2: spanSegment(tokens:>:mate/d:HEAD, "
+ "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ "spanElementWithAttribute(<tokens:c:s />, spanAttribute(tokens:@root)))), <tokens:c:vp />))",
sq.toString());
}
@@ -72,7 +72,7 @@
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus([1,2]spanSegment(focus(2: spanSegment(tokens:>:mate/d:HEAD, "
+ "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+ "spanElementWithAttribute(<tokens:c:s />, spanAttribute(tokens:type:top)))), <tokens:c:vp />))",
sq.toString());
}
@@ -85,7 +85,8 @@
"/queries/relation/relation-only.json").getFile();
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
- assertEquals("focus([1,2]tokens:<:mate/d:HEAD)", sq.toString());
+ assertEquals("focus(#[1,2]spanRelation(tokens:>:mate/d:HEAD))",
+ sq.toString());
}
@Test
@@ -96,18 +97,41 @@
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus(1: spanSegment(tokens:<:mate/d:HEAD, <tokens:np />))",
+ "focus(1: focus(#[1,2]spanSegment(spanRelation(tokens:<:mate/d:HEAD), {1: <tokens:c:np />})))",
sq.toString());
}
@Test
- public void testFocusTarget () throws QueryException {
+ public void testFocusTarget() throws QueryException {
String filepath = getClass().getResource(
"/queries/relation/focus-target.json").getFile();
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
- "focus(2: spanSegment(tokens:>:mate/d:HEAD, <tokens:s />))",
+ "focus(2: focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation("
+ + "tokens:>:mate/d:HEAD), {1: <tokens:c:s />})), {2: <tokens:c:np />})))",
+ sq.toString());
+ }
+
+ @Test
+ public void testFocusEmptyTarget() throws QueryException {
+ String filepath = getClass().getResource(
+ "/queries/relation/focus-empty-target.json").getFile();
+ SpanQueryWrapper sqwi = getJSONQuery(filepath);
+ SpanQuery sq = sqwi.toQuery();
+ assertEquals(
+ "focus(2: focus(#[1,2]spanSegment({2: target:spanRelation(tokens:>:mate/d:HEAD)}, {1: <tokens:c:s />})))",
+ sq.toString());
+ }
+
+ @Test
+ public void testFocusEmptyBoth() throws QueryException {
+ String filepath = getClass().getResource(
+ "/queries/relation/focus-empty-both.json").getFile();
+ SpanQueryWrapper sqwi = getJSONQuery(filepath);
+ SpanQuery sq = sqwi.toQuery();
+ assertEquals(
+ "focus(2: focus(#[1,2]{1: source:{2: target:spanRelation(tokens:>:mate/d:HEAD)}}))",
sq.toString());
}
}
diff --git a/src/test/java/de/ids_mannheim/korap/search/TestKrill.java b/src/test/java/de/ids_mannheim/korap/search/TestKrill.java
index 622a80b..8c3dd7d 100644
--- a/src/test/java/de/ids_mannheim/korap/search/TestKrill.java
+++ b/src/test/java/de/ids_mannheim/korap/search/TestKrill.java
@@ -1,35 +1,31 @@
package de.ids_mannheim.korap.search;
-import java.util.*;
-import java.io.*;
+import static de.ids_mannheim.korap.TestSimple.getString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
-import static de.ids_mannheim.korap.TestSimple.*;
+import java.io.IOException;
+import java.util.HashMap;
-import de.ids_mannheim.korap.Krill;
-import de.ids_mannheim.korap.KrillMeta;
-import de.ids_mannheim.korap.KrillCollection;
-import de.ids_mannheim.korap.KrillQuery;
-import de.ids_mannheim.korap.KrillIndex;
-import de.ids_mannheim.korap.query.QueryBuilder;
-import de.ids_mannheim.korap.index.FieldDocument;
-import de.ids_mannheim.korap.collection.CollectionBuilder;
-import de.ids_mannheim.korap.response.SearchContext;
-import de.ids_mannheim.korap.response.Result;
-import java.nio.file.Files;
-import java.nio.file.FileSystem;
-import java.nio.file.Path;
-import java.nio.charset.StandardCharsets;
-import java.nio.ByteBuffer;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.JsonNode;
-
-import static org.junit.Assert.*;
import org.junit.Test;
-import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import de.ids_mannheim.korap.Krill;
+import de.ids_mannheim.korap.KrillCollection;
+import de.ids_mannheim.korap.KrillIndex;
+import de.ids_mannheim.korap.KrillMeta;
+import de.ids_mannheim.korap.collection.CollectionBuilder;
+import de.ids_mannheim.korap.index.FieldDocument;
+import de.ids_mannheim.korap.query.QueryBuilder;
+import de.ids_mannheim.korap.response.Match;
+import de.ids_mannheim.korap.response.Result;
+import de.ids_mannheim.korap.response.SearchContext;
+
@RunWith(JUnit4.class)
public class TestKrill {
@Test
@@ -635,6 +631,14 @@
Result kr = ks.apply(ki);
assertEquals(kr.getSerialQuery(),
"focus(1: spanContain(<tokens:base/s:s />, {1: tokens:s:Leben}))");
+ assertEquals(40, kr.getMatch(0).getStartPos());
+ assertEquals(41, kr.getMatch(0).getEndPos());
+
+ for (Match km : kr.getMatches()) {
+ System.out.println(km.getStartPos() + "," + km.getEndPos() + " "
+ + km.getSnippetBrackets());
+ }
+
assertEquals(
kr.getMatch(0).getSnippetBrackets(),
"... Initiative\" eine neue politische Gruppierung ins "
diff --git a/src/test/resources/queries/relation/focus-empty-both.json b/src/test/resources/queries/relation/focus-empty-both.json
new file mode 100644
index 0000000..1e9fa16
--- /dev/null
+++ b/src/test/resources/queries/relation/focus-empty-both.json
@@ -0,0 +1,39 @@
+{
+ "query": {
+ "@type": "koral:reference",
+ "operation": "operation:focus",
+ "classRef": [2],
+ "operands": [{
+ "@type": "koral:group",
+ "operation": "operation:relation",
+ "operands": [
+ {
+ "@type": "koral:group",
+ "operation": "operation:class",
+ "classOut": 1,
+ "operands": [{
+ "@type": "koral:token"
+ }]
+ },
+ {
+ "@type": "koral:group",
+ "operation": "operation:class",
+ "classOut": 2,
+ "operands": [{
+ "@type": "koral:token"
+ }]
+ }
+ ],
+ "relation": {
+ "@type": "koral:relation",
+ "wrap": {
+ "@type": "koral:term",
+ "foundry": "mate",
+ "layer": "d",
+ "key": "HEAD"
+ }
+ }
+ }]
+ },
+ "meta": {}
+}
diff --git a/src/test/resources/queries/relation/focus-empty-target.json b/src/test/resources/queries/relation/focus-empty-target.json
new file mode 100644
index 0000000..78ac125
--- /dev/null
+++ b/src/test/resources/queries/relation/focus-empty-target.json
@@ -0,0 +1,42 @@
+{
+ "query": {
+ "@type": "koral:reference",
+ "operation": "operation:focus",
+ "classRef": [2],
+ "operands": [{
+ "@type": "koral:group",
+ "operation": "operation:relation",
+ "operands": [
+ {
+ "@type": "koral:group",
+ "operation": "operation:class",
+ "classOut": 1,
+ "operands": [{
+ "@type": "koral:span",
+ "layer": "c",
+ "key": "s",
+ "match": "match:eq"
+ }]
+ },
+ {
+ "@type": "koral:group",
+ "operation": "operation:class",
+ "classOut": 2,
+ "operands": [{
+ "@type": "koral:token"
+ }]
+ }
+ ],
+ "relation": {
+ "@type": "koral:relation",
+ "wrap": {
+ "@type": "koral:term",
+ "foundry": "mate",
+ "layer": "d",
+ "key": "HEAD"
+ }
+ }
+ }]
+ },
+ "meta": {}
+}
diff --git a/src/test/resources/queries/relation/focus-source.json b/src/test/resources/queries/relation/focus-source.json
index d934a3b..68d5ce4 100644
--- a/src/test/resources/queries/relation/focus-source.json
+++ b/src/test/resources/queries/relation/focus-source.json
@@ -11,8 +11,15 @@
"@type": "koral:token"
},
{
- "@type": "koral:span",
- "key": "np"
+ "@type": "koral:group",
+ "operation": "operation:class",
+ "classOut": 1,
+ "operands": [{
+ "@type": "koral:span",
+ "layer": "c",
+ "key": "np",
+ "match": "match:eq"
+ }]
}
],
"relation": {
diff --git a/src/test/resources/queries/relation/focus-target.json b/src/test/resources/queries/relation/focus-target.json
index daec972..46282a8 100644
--- a/src/test/resources/queries/relation/focus-target.json
+++ b/src/test/resources/queries/relation/focus-target.json
@@ -8,11 +8,26 @@
"operation": "operation:relation",
"operands": [
{
- "@type": "koral:span",
- "key": "s"
+ "@type": "koral:group",
+ "operation": "operation:class",
+ "classOut": 1,
+ "operands": [{
+ "@type": "koral:span",
+ "layer": "c",
+ "key": "s",
+ "match": "match:eq"
+ }]
},
{
- "@type": "koral:token"
+ "@type": "koral:group",
+ "operation": "operation:class",
+ "classOut": 2,
+ "operands": [{
+ "@type": "koral:span",
+ "layer": "c",
+ "key": "np",
+ "match": "match:eq"
+ }]
}
],
"relation": {