Implemented relation queries with regex.
Change-Id: I1dafc835f6034d90a350d9688acdcf54bac28124
diff --git a/Changes b/Changes
index f39c756..a8f1cbf 100644
--- a/Changes
+++ b/Changes
@@ -1,4 +1,4 @@
-0.55.9 2017-11-16
+0.55.9 2017-12-19
- [bugfix] Serialize token identifier correctly for
new corpora with text siglen (diewald)
- [bugfix] Extend bytebuffer for relation payloads (diewald)
@@ -6,6 +6,8 @@
repositioning can result in exceeding the string (diewald)
- [bugfix] Set correct start position of token-token-relations
in snippet generation (diewald)
+ - [bugfix] Token cannot contain another token or element (margaretha)
+ - [feature] Enabled searching relation query using regex (margaretha)
0.55.8 2017-09-05
- [feature] Retrieve and display pagebreaks (diewald)
diff --git a/src/main/java/de/ids_mannheim/korap/KrillQuery.java b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
index 4f5901f..8e30b7a 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
@@ -5,6 +5,7 @@
import java.util.List;
import java.util.Iterator;
+import org.apache.lucene.search.RegexpQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -13,6 +14,7 @@
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import de.ids_mannheim.korap.constants.RelationDirection;
import de.ids_mannheim.korap.query.QueryBuilder;
import de.ids_mannheim.korap.query.SpanWithinQuery;
import de.ids_mannheim.korap.query.wrap.SpanAlterQueryWrapper;
@@ -323,7 +325,7 @@
return this._termFromJson(json);
// This is an ugly hack
- return this._termFromJson(json.get("wrap"), "<>:");
+ return this._termFromJson(json.get("wrap"), true);
};
// Unknown query type
@@ -566,9 +568,12 @@
SpanQueryWrapper operand1 = this._fromKoral(operands.get(0), true);
SpanQueryWrapper operand2 = this._fromKoral(operands.get(1), true);
- String direction = ">:";
+ RelationDirection direction;
if (operand1.isEmpty() && !operand2.isEmpty()) {
- direction = "<:";
+ direction = RelationDirection.LEFT; // "<:";
+ }
+ else{
+ direction = RelationDirection.RIGHT; // ">:"
}
if (!relation.has("@type")){
@@ -576,15 +581,20 @@
"JSON-LD group has no @type attribute");
}
- SpanRelationWrapper spanRelationWrapper;
if (relation.get("@type").asText().equals("koral:relation")) {
+ SpanRelationWrapper spanRelationWrapper;
+ SpanQueryWrapper relationTermWrapper;
if (!relation.has("wrap")) {
- throw new QueryException(718, "Missing relation term");
+ throw new QueryException(718, "Missing relation term.");
+ }
+ else{
+ relationTermWrapper =
+ _termFromJson(relation.get("wrap"), false, direction);
+ spanRelationWrapper = new SpanRelationWrapper(relationTermWrapper, operand1, operand2);
}
- SpanQueryWrapper relationWrapper =
- _termFromJson(relation.get("wrap"), direction);
- return new SpanRelationWrapper(relationWrapper, operand1, operand2);
+ spanRelationWrapper.setDirection(direction);
+ return spanRelationWrapper;
}
else {
throw new QueryException(713, "Query type is not supported");
@@ -999,13 +1009,8 @@
return sseqqw;
};
- private SpanQueryWrapper _segFromJson (JsonNode json)
- throws QueryException {
- return _segFromJson(json, null);
- }
-
// Deserialize koral:token
- private SpanQueryWrapper _segFromJson (JsonNode json, String direction)
+ private SpanQueryWrapper _segFromJson (JsonNode json)
throws QueryException {
if (!json.has("@type"))
@@ -1038,7 +1043,7 @@
// return this.seg().without(ssqw);
//
// case "match:eq":
- return this._termFromJson(json, direction);
+ return this._termFromJson(json);
// };
//
// throw new QueryException(741, "Match relation unknown");
@@ -1095,13 +1100,16 @@
private SpanQueryWrapper _termFromJson (JsonNode json)
throws QueryException {
- return this._termFromJson(json, null);
+ return this._termFromJson(json, false, null);
}
-
+ private SpanQueryWrapper _termFromJson (JsonNode json, boolean isSpan)
+ throws QueryException {
+ return this._termFromJson(json, isSpan, null);
+ }
// Deserialize koral:term
// TODO: Not optimal as it does not respect non-term
- private SpanQueryWrapper _termFromJson (JsonNode json, String direction)
+ private SpanQueryWrapper _termFromJson (JsonNode json, boolean isSpan, RelationDirection direction)
throws QueryException {
if (!json.has("@type")) {
@@ -1124,10 +1132,9 @@
}
};
- // Ugly direction hack
- if (direction != null && direction.equals("<>:")) {
+ // Empty koral:span hack
+ if (isSpan) {
isTerm = false;
- direction = null;
};
// <legacy>
@@ -1154,7 +1161,7 @@
StringBuilder value = new StringBuilder();
if (direction != null)
- value.append(direction);
+ value.append(direction.value());
// expect orth? expect lemma?
// s:den | i:den | cnx/l:die | mate/m:mood:ind | cnx/syn:@PREMOD |
diff --git a/src/main/java/de/ids_mannheim/korap/constants/RelationDirection.java b/src/main/java/de/ids_mannheim/korap/constants/RelationDirection.java
new file mode 100644
index 0000000..e20055d
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/constants/RelationDirection.java
@@ -0,0 +1,15 @@
+package de.ids_mannheim.korap.constants;
+
+public enum RelationDirection {
+ LEFT("<:"), RIGHT(">:");
+
+ private String value;
+
+ RelationDirection (String value) {
+ this.value = value;
+ }
+
+ public String value () {
+ return value;
+ }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java
index de77ef4..866dbc7 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java
@@ -10,6 +10,7 @@
import org.apache.lucene.search.spans.Spans;
import org.apache.lucene.util.Bits;
+import de.ids_mannheim.korap.constants.RelationDirection;
import de.ids_mannheim.korap.query.spans.FocusSpans;
/**
@@ -81,7 +82,7 @@
SpanFocusQuery sq = null;
SpanFocusQuery sq2 = null;
// match source and then target
- if (relationQuery.getDirection() == 0) {
+ if (relationQuery.getDirection().equals(RelationDirection.RIGHT)) {
sq = new SpanFocusQuery(
new SpanSegmentQuery(relationQuery, operandQuery, true),
relation.getTempTargetNum());
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 ea71d63..fe9d3b3 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanRelationQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanRelationQuery.java
@@ -9,11 +9,11 @@
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.SpanTermQuery;
import org.apache.lucene.search.spans.Spans;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.ToStringUtils;
+import de.ids_mannheim.korap.constants.RelationDirection;
import de.ids_mannheim.korap.query.spans.RelationSpans;
/**
@@ -54,7 +54,7 @@
*/
public class SpanRelationQuery extends SimpleSpanQuery {
- private int direction = 0; // >
+ private RelationDirection direction;
private byte tempSourceNum = 1;
private byte tempTargetNum = 2;
private byte sourceClass;
@@ -75,29 +75,32 @@
* payloads are to be collected, otherwise
* <code>false</code>.
*/
- public SpanRelationQuery (SpanQuery firstClause, boolean collectPayloads) {
+ public SpanRelationQuery (SpanQuery firstClause, boolean collectPayloads,
+ RelationDirection direction) {
super(firstClause, collectPayloads);
- SpanTermQuery st = (SpanTermQuery) firstClause;
- String direction = st.getTerm().text().substring(0, 1);
- if (direction.equals("<")) {
- this.direction = 1;
- }
+ this.direction = direction;
+// SpanTermQuery st = (SpanTermQuery) firstClause;
+// String direction = st.getTerm().text().substring(0, 1);
+// if (direction.equals("<")) {
+// this.direction = 1;
+// }
}
- 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);
- }
+// 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 () {
SimpleSpanQuery sq = new SpanRelationQuery(
- (SpanQuery) this.firstClause.clone(), this.collectPayloads);
+ (SpanQuery) this.firstClause.clone(), this.collectPayloads,
+ this.direction);
return sq;
}
@@ -136,12 +139,12 @@
}
- public int getDirection () {
+ public RelationDirection getDirection () {
return direction;
}
- public void setDirection (int direction) {
+ public void setDirection (RelationDirection direction) {
this.direction = direction;
}
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 51bf64f..c5e9487 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
@@ -14,6 +14,7 @@
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.util.Bits;
+import de.ids_mannheim.korap.constants.RelationDirection;
import de.ids_mannheim.korap.query.SpanFocusQuery;
@@ -157,10 +158,10 @@
if (firstSpans instanceof RelationSpans && classNumbers.size() == 1) {
RelationSpans relationSpans = (RelationSpans) firstSpans;
- int direction = relationSpans.getDirection();
+ RelationDirection direction = relationSpans.getDirection();
if (classNumbers.get(0) == relationSpans.getTempSourceNum()) {
- if (direction == 0) {
+ if (direction.equals(RelationDirection.RIGHT)) {
setSpanId(relationSpans.getLeftId());
}
else {
@@ -168,7 +169,7 @@
}
}
else if (classNumbers.get(0) == relationSpans.getTempTargetNum()) {
- if (direction == 0) {
+ if (direction.equals(RelationDirection.RIGHT)) {
setSpanId(relationSpans.getRightId());
}
else {
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 ca467fc..a10e770 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
@@ -10,11 +10,13 @@
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext;
+import org.apache.lucene.search.spans.Spans;
import org.apache.lucene.search.spans.TermSpans;
import org.apache.lucene.util.Bits;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import de.ids_mannheim.korap.constants.RelationDirection;
import de.ids_mannheim.korap.query.SpanRelationQuery;
/**
@@ -52,8 +54,8 @@
public class RelationSpans extends RelationBaseSpans {
private int currentDoc, currentPosition;
- private int direction;
- private TermSpans relationTermSpan;
+ private RelationDirection direction;
+ private Spans relationTermSpan;
protected Logger logger = LoggerFactory.getLogger(RelationSpans.class);
private List<CandidateSpan> candidateList;
@@ -96,7 +98,7 @@
targetClass = relationSpanQuery.getTargetClass();
candidateList = new ArrayList<>();
- relationTermSpan = (TermSpans) firstSpans;
+ relationTermSpan = firstSpans;
hasMoreSpans = relationTermSpan.next();
}
@@ -138,8 +140,10 @@
}
else {
setCandidateList();
- currentDoc = relationTermSpan.doc();
- currentPosition = relationTermSpan.start();
+ if(hasMoreSpans){
+ currentDoc = relationTermSpan.doc();
+ currentPosition = relationTermSpan.start();
+ }
}
}
return false;
@@ -155,6 +159,7 @@
* @throws IOException
*/
private void setCandidateList () throws IOException {
+ logger.debug("hasMoreSpans "+hasMoreSpans+" "+relationTermSpan.doc());
while (hasMoreSpans && relationTermSpan.doc() == currentDoc
&& relationTermSpan.start() == currentPosition) {
@@ -257,7 +262,7 @@
if (relationTermSpan.isPayloadAvailable()) {
payload.addAll(relationTermSpan.getPayload());
}
- if (direction == 0) {
+ if (direction.equals(RelationDirection.RIGHT)) {
payload.add(createClassPayload(cs.getLeftStart(), cs.getLeftEnd(),
tempSourceNum, false));
payload.add(createClassPayload(cs.getRightStart(), cs.getRightEnd(),
@@ -393,12 +398,12 @@
}
- public int getDirection () {
+ public RelationDirection getDirection () {
return direction;
}
- public void setDirection (int direction) {
+ public void setDirection (RelationDirection direction) {
this.direction = direction;
}
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 d7b0f6d..fe980c9 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,8 +1,10 @@
package de.ids_mannheim.korap.query.wrap;
+import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
+import de.ids_mannheim.korap.constants.RelationDirection;
import de.ids_mannheim.korap.query.SpanFocusQuery;
import de.ids_mannheim.korap.query.SpanRelationMatchQuery;
import de.ids_mannheim.korap.query.SpanRelationQuery;
@@ -13,7 +15,7 @@
private SpanQueryWrapper relationQuery;
private SpanQueryWrapper subQuery1;
private SpanQueryWrapper subQuery2;
-
+ private RelationDirection direction;
public SpanRelationWrapper (SpanQueryWrapper relationWrapper,
SpanQueryWrapper operand1,
@@ -43,12 +45,15 @@
return null;
}
- SpanTermQuery relationTermQuery = (SpanTermQuery) relationQuery
+ SpanQuery relationTermQuery = relationQuery
.retrieveNode(this.retrieveNode).toFragmentQuery();
+
+// SpanTermQuery relationTermQuery = (SpanTermQuery) relationQuery
+// .retrieveNode(this.retrieveNode).toFragmentQuery();
if (relationTermQuery == null)
return null;
- SpanRelationQuery rq = new SpanRelationQuery(relationTermQuery, true);
+ SpanRelationQuery rq = new SpanRelationQuery(relationTermQuery, true, direction);
SpanQuery subq1, subq2;
if (subQuery1.isEmpty) {
@@ -94,4 +99,11 @@
fq.setSorted(false);
return fq;
}
+
+ public void setDirection (RelationDirection direction) {
+ this.direction = direction;
+ }
+ public RelationDirection getDirection () {
+ return direction;
+ }
}
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestFocusIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestFocusIndex.java
index 9228c78..1ea89d8 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestFocusIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestFocusIndex.java
@@ -10,6 +10,7 @@
import org.junit.Test;
import de.ids_mannheim.korap.KrillIndex;
+import de.ids_mannheim.korap.constants.RelationDirection;
import de.ids_mannheim.korap.query.SpanFocusQuery;
import de.ids_mannheim.korap.query.SpanNextQuery;
import de.ids_mannheim.korap.query.SpanRelationQuery;
@@ -36,7 +37,7 @@
ki.commit();
SpanRelationQuery sq = new SpanRelationQuery(
new SpanTermQuery(new Term("base", ">:xip/syntax-dep_rel")),
- true);
+ true, RelationDirection.RIGHT);
sq.setSourceClass((byte) 1);
SpanFocusQuery sfq = new SpanFocusQuery(sq, (byte) 1);
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java
index 177dbc7..b5d3412 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java
@@ -11,6 +11,7 @@
import org.junit.Test;
import de.ids_mannheim.korap.KrillIndex;
+import de.ids_mannheim.korap.constants.RelationDirection;
import de.ids_mannheim.korap.query.DistanceConstraint;
import de.ids_mannheim.korap.query.SpanClassQuery;
import de.ids_mannheim.korap.query.SpanDistanceQuery;
@@ -44,7 +45,8 @@
SpanFocusQuery sfq1 = new SpanFocusQuery(snq1, (byte) 2);
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", "<:child-of")), true);
+ new SpanTermQuery(new Term("base", "<:child-of")), true,
+ RelationDirection.LEFT);
SpanElementQuery seq2 = new SpanElementQuery("base", "pp");
SpanClassQuery scq3 = new SpanClassQuery(seq2, (byte) 3);
@@ -126,7 +128,7 @@
// nn -> prp
SpanRelationQuery srq = new SpanRelationQuery(
new SpanTermQuery(new Term("tokens", ">:stanford/d:tag")),
- true);
+ true, RelationDirection.RIGHT);
SpanRelationMatchQuery rq = new SpanRelationMatchQuery(srq, sfq2, scq2,
true);
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 505d2bf..4d2ba30 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
@@ -5,11 +5,14 @@
import java.io.IOException;
import org.apache.lucene.index.Term;
+import org.apache.lucene.sandbox.queries.regex.RegexQuery;
+import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.junit.Test;
import de.ids_mannheim.korap.KrillIndex;
+import de.ids_mannheim.korap.constants.RelationDirection;
import de.ids_mannheim.korap.query.SpanAttributeQuery;
import de.ids_mannheim.korap.query.SpanClassQuery;
import de.ids_mannheim.korap.query.SpanElementQuery;
@@ -19,6 +22,7 @@
import de.ids_mannheim.korap.query.SpanSegmentQuery;
import de.ids_mannheim.korap.query.SpanTermWithIdQuery;
import de.ids_mannheim.korap.query.SpanWithAttributeQuery;
+import de.ids_mannheim.korap.response.Match;
import de.ids_mannheim.korap.response.Result;
/*
@@ -114,6 +118,30 @@
+ ":xip/syntax-dep_rel$<b>33<i>6<i>7<i>6<i>9<s>2<s>1<s>0]");
return fd;
}
+
+ public static FieldDocument createFieldDoc3 () {
+ FieldDocument fd = new FieldDocument();
+ fd.addString("ID", "doc-1");
+ fd.addTV("base", "ceccecdeed",
+ "[(0-1)s:c$<s>2|<>:p$<b>64<i>0<i>3<i>3<b>0<s>1|_0$<i>0<i>1|"
+ + ">:xip/dep_rel$<b>35<i>0<i>1<i>1<i>2<i>3<i>6<i>9<s>1<s>1<s>2|"
+ + ">:xip/dep_rel$<b>33<i>1<i>2<i>6<i>9<s>2<s>1<s>0|"
+ + "@:func=subj$<b>18<s>2]"
+ + "[(1-2)s:e|_1$<i>1<i>2|<>:p$<b>64<i>1<i>3<i>3<b>0<s>1]"
+ + "[(2-3)s:c|_2$<i>2<i>3]"
+ + "[(3-4)s:c|s:b|_3$<i>3<i>4]"
+ + "[(4-5)s:e|s:d|_4$<i>4<i>5]"
+ + "[(5-6)s:c|_5$<i>5<i>6]"
+ + "[(6-7)s:d$<s>2|<>:p$<b>64<i>6<i>9<i>9<b>0<s>1|_6$<i>6<i>7|"
+ + ">:xip/dep_rel$<b>34<i>3<i>4<i>9<i>9<s>1<s>1<s>0|"
+ + "<:xip/dep_rel$<b>35<i>3<i>4<i>4<i>5<i>9<i>1<i>3<s>1<s>1<s>2|"
+ + "<:xip/dep_rel$<b>34<i>5<i>6<i>9<i>1<s>1<s>2<s>0|"
+ + "@:func=obj$<b>18<s>2]" + "[(7-8)s:e|_7$<i>7<i>8]"
+ + "[(8-9)s:e|s:b|_8$<i>8<i>9]"
+ + "[(9-10)s:d$<s>1|_9$<i>9<i>10|<"
+ + ":xip/dep_rel$<b>33<i>6<i>7<i>6<i>9<s>2<s>1<s>0]");
+ return fd;
+ }
public static FieldDocument createFieldDoc2 () {
@@ -215,6 +243,29 @@
// }
//
// }
+ @Test
+ public void testRelationWithRegex () throws IOException {
+ ki.addDoc(createFieldDoc0());
+ ki.addDoc(createFieldDoc3());
+ ki.commit();
+
+ SpanQuery sq;
+ sq = new SpanRelationQuery(
+ new SpanMultiTermQueryWrapper<RegexQuery>(
+ new RegexQuery(new Term("base", ">:xip/.*"))),
+ true, RelationDirection.RIGHT);
+ kr = ki.search(sq, (short) 10);
+
+ assertEquals((long) 7, kr.getTotalResults());
+
+ sq = new SpanRelationQuery(
+ new SpanMultiTermQueryWrapper<RegexQuery>(
+ new RegexQuery(new Term("base", "<:xip/.*"))),
+ true, RelationDirection.LEFT);
+ kr = ki.search(sq, (short) 10);
+
+ assertEquals((long) 7, kr.getTotalResults());
+ }
/**
* Relations: token to token, token to span, span to span
@@ -227,7 +278,7 @@
SpanRelationQuery sq = new SpanRelationQuery(
new SpanTermQuery(new Term("base", ">:xip/syntax-dep_rel")),
- true);
+ true, RelationDirection.RIGHT);
kr = ki.search(sq, (short) 10);
assertEquals((long) 7, kr.getTotalResults());
@@ -269,7 +320,7 @@
SpanRelationQuery sq = new SpanRelationQuery(
new SpanTermQuery(new Term("base", "<:xip/syntax-dep_rel")),
- true);
+ true, RelationDirection.LEFT);
kr = ki.search(sq, (short) 10);
assertEquals((long) 7, kr.getTotalResults());
@@ -306,7 +357,8 @@
// child-of relations
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:child-of")), true);
+ new SpanTermQuery(new Term("base", ">:child-of")),
+ true, RelationDirection.RIGHT);
kr = ki.search(srq, (short) 20);
assertEquals((long) 13, kr.getTotalResults());
@@ -334,7 +386,8 @@
ki.commit();
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:child-of")), true);
+ new SpanTermQuery(new Term("base", ">:child-of")),
+ true, RelationDirection.RIGHT);
SpanFocusQuery fq = new SpanFocusQuery(srq, srq.getTempClassNumbers());
fq.setMatchTemporaryClass(true);
@@ -382,7 +435,8 @@
SpanClassQuery scq1 = new SpanClassQuery(seq1, (byte) 1);
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:child-of")), true);
+ new SpanTermQuery(new Term("base", ">:child-of")),
+ true, RelationDirection.RIGHT);
SpanRelationMatchQuery rm = new SpanRelationMatchQuery(srq, scq1, true);
SpanFocusQuery rv = new SpanFocusQuery(rm, (byte) 1);
@@ -406,7 +460,8 @@
// return all parents that are NP
srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", "<:child-of")), true);
+ new SpanTermQuery(new Term("base", "<:child-of")),
+ true, RelationDirection.LEFT);
rm = new SpanRelationMatchQuery(srq, scq1, true);
rv = new SpanFocusQuery(rm, (byte) 1);
kr = ki.search(rv, (short) 10);
@@ -439,7 +494,8 @@
// target of a dependency relation
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", "<:dep")), true);
+ new SpanTermQuery(new Term("base", "<:dep")), true,
+ RelationDirection.LEFT);
kr = ki.search(srq, (short) 10);
assertEquals((long) 6, kr.getTotalResults());
@@ -482,7 +538,8 @@
SpanClassQuery scq1 = new SpanClassQuery(seq1, (byte) 1);
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:child-of")), true);
+ new SpanTermQuery(new Term("base", ">:child-of")), true,
+ RelationDirection.RIGHT);
srq.setTargetClass((byte) 2);
SpanRelationMatchQuery rm = new SpanRelationMatchQuery(srq, scq1, true);
@@ -528,7 +585,8 @@
SpanTermWithIdQuery tq = new SpanTermWithIdQuery(
new Term("base", "pos:NN"), true);
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", "<:dep")), true);
+ new SpanTermQuery(new Term("base", "<:dep")), true,
+ RelationDirection.LEFT);
srq.setSourceClass((byte) 1);
SpanRelationMatchQuery rm = new SpanRelationMatchQuery(srq, tq, true);
SpanQuery rv = new SpanFocusQuery(rm, (byte) 1);
@@ -544,7 +602,8 @@
// return target of dep relations from pos:NN
srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:dep")), true);
+ new SpanTermQuery(new Term("base", ">:dep")), true,
+ RelationDirection.RIGHT);
srq.setTargetClass((byte) 1);
rm = new SpanRelationMatchQuery(srq, tq, true);
rv = new SpanFocusQuery(rm, (byte) 1);
@@ -578,7 +637,8 @@
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);
+ new SpanTermQuery(new Term("base", "<:child-of")),
+ true, RelationDirection.LEFT);
srq.setSourceClass((byte) 2);
SpanRelationMatchQuery rm = new SpanRelationMatchQuery(srq, scq1, true);
SpanFocusQuery rv = new SpanFocusQuery(rm, (byte) 2);
@@ -620,7 +680,8 @@
SpanClassQuery scq2 = new SpanClassQuery(seq, (byte) 2);
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:child-of")), true);
+ new SpanTermQuery(new Term("base", ">:child-of")),
+ true, RelationDirection.RIGHT);
srq.setSourceClass((byte) 1);
srq.setTargetClass((byte) 2);
@@ -661,7 +722,8 @@
assertEquals(6, kr.getMatch(1).getEndPos());
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:child-of")), true);
+ new SpanTermQuery(new Term("base", ">:child-of")),
+ true, RelationDirection.RIGHT);
srq.setSourceClass((byte) 1);
srq.setTargetClass((byte) 2);
@@ -752,7 +814,8 @@
assertEquals((long) 3, kr.getTotalResults());
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:child-of")), true);
+ new SpanTermQuery(new Term("base", ">:child-of")),
+ true, RelationDirection.RIGHT);
srq.setSourceClass((byte) 1);
srq.setTargetClass((byte) 2);
kr = ki.search(srq, (short) 20);
@@ -834,7 +897,8 @@
assertEquals((long) 3, kr.getTotalResults());
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:child-of")), true);
+ new SpanTermQuery(new Term("base", ">:child-of")),
+ true, RelationDirection.RIGHT);
srq.setSourceClass((byte) 1);
srq.setTargetClass((byte) 2);
kr = ki.search(srq, (short) 20);
@@ -908,7 +972,8 @@
assertEquals((long) 3, kr.getTotalResults());
SpanRelationQuery srq = new SpanRelationQuery(
- new SpanTermQuery(new Term("base", ">:child-of")), true);
+ new SpanTermQuery(new Term("base", ">:child-of")),
+ true, RelationDirection.RIGHT);
srq.setSourceClass((byte) 1);
srq.setTargetClass((byte) 2);
kr = ki.search(srq, (short) 20);
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 2423ae6..67acf96 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java
@@ -105,12 +105,13 @@
"focus(#[1,2]spanSegment(spanRelation(tokens:>:mate/d:HEAD), <tokens:c:s />))",
sq.toString());
}
-
+
@Test
public void testMatchRelationSourceToken () throws QueryException {
//
String filepath = getClass()
- .getResource("/queries/relation/match-source-token.json").getFile();
+ .getResource("/queries/relation/match-source-token.json")
+ .getFile();
SpanQueryWrapper sqwi = getJSONQuery(filepath);
SpanQuery sq = sqwi.toQuery();
assertEquals(
@@ -118,7 +119,7 @@
sq.toString());
}
-
+
@Test
public void testMatchRelationTarget () throws QueryException {
//
@@ -240,8 +241,21 @@
sq.toString());
}
+ @Test
+ public void testTypedRelationWithAnnotationRegex () throws QueryException {
+ String filepath = getClass()
+ .getResource(
+ "/queries/relation/typed-relation-with-key-regex.json")
+ .getFile();
+ SpanQueryWrapper sqwi = getJSONQuery(filepath);
+ SpanQuery sq = sqwi.toQuery();
+ assertEquals("focus(#[1,2]spanSegment(<tokens:corenlp/c:NP />, "
+ + "focus(#2: spanSegment(spanRelation(SpanMultiTermQueryWrapper(tokens:/>:malt/d:.*/)), "
+ + "<tokens:corenlp/c:VP />))))", sq.toString());
+ }
// EM: should relation term allow empty key?
+ // EM: or should this be interpreted as any key, i.e. [func=/.*/]
@Test
public void testTypedRelationWithoutKey () throws QueryException {
@@ -297,11 +311,11 @@
SpanQuery sq = sqwi.toQuery();
assertEquals(
"focus(#[1,2]spanSegment(tokens:tt/p:VVINF, "
- + "focus(#2: spanSegment("
- + "spanRelation(tokens:>:malt/d:KONJ), tokens:tt/p:KOUI))))",
+ + "focus(#2: spanSegment("
+ + "spanRelation(tokens:>:malt/d:KONJ), tokens:tt/p:KOUI))))",
sq.toString());
}
-
+
// EM: handle empty koral:span
}
diff --git a/src/test/resources/queries/relation/indirect-typed-relation-without-key.json b/src/test/resources/queries/relation/indirect-typed-relation-without-key.json
new file mode 100644
index 0000000..f641b8f
--- /dev/null
+++ b/src/test/resources/queries/relation/indirect-typed-relation-without-key.json
@@ -0,0 +1,41 @@
+{
+ "@context": "http://korap.ids-mannheim.de/ns/koral/0.3/context.jsonld",
+ "query": {
+ "operation": "operation:relation",
+ "operands": [
+ {
+ "wrap": {
+ "@type": "koral:term",
+ "layer": "c",
+ "foundry": "corenlp",
+ "match": "match:eq",
+ "key": "VP"
+ },
+ "@type": "koral:span"
+ },
+ {
+ "wrap": {
+ "@type": "koral:term",
+ "layer": "c",
+ "foundry": "corenlp",
+ "match": "match:eq",
+ "key": "NP"
+ },
+ "@type": "koral:span"
+ }
+ ],
+ "@type": "koral:group",
+ "relType": {
+ "wrap": {
+ "@type": "koral:term",
+ "layer": "d",
+ "foundry": "malt"
+ },
+ "@type": "koral:relation",
+ "boundary": {
+ "min": 0,
+ "@type": "koral:boundary"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/queries/relation/indirect-typed-relation.json b/src/test/resources/queries/relation/indirect-typed-relation.json
new file mode 100644
index 0000000..17a92ed
--- /dev/null
+++ b/src/test/resources/queries/relation/indirect-typed-relation.json
@@ -0,0 +1,43 @@
+{
+ "@context": "http://korap.ids-mannheim.de/ns/koral/0.3/context.jsonld",
+ "query": {
+ "operation": "operation:relation",
+ "operands": [
+ {
+ "wrap": {
+ "@type": "koral:term",
+ "layer": "c",
+ "foundry": "corenlp",
+ "match": "match:eq",
+ "key": "VP"
+ },
+ "@type": "koral:span"
+ },
+ {
+ "wrap": {
+ "@type": "koral:term",
+ "layer": "c",
+ "foundry": "corenlp",
+ "match": "match:eq",
+ "key": "NP"
+ },
+ "@type": "koral:span"
+ }
+ ],
+ "@type": "koral:group",
+ "relType": {
+ "wrap": {
+ "@type": "koral:term",
+ "layer": "d",
+ "foundry": "malt",
+ "match": "match:eq",
+ "key": "DET"
+ },
+ "@type": "koral:relation",
+ "boundary": {
+ "min": 0,
+ "@type": "koral:boundary"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/queries/relation/typed-relation-with-key-regex.json b/src/test/resources/queries/relation/typed-relation-with-key-regex.json
new file mode 100644
index 0000000..bee6c78
--- /dev/null
+++ b/src/test/resources/queries/relation/typed-relation-with-key-regex.json
@@ -0,0 +1,40 @@
+{
+ "@context": "http://korap.ids-mannheim.de/ns/koral/0.3/context.jsonld",
+ "query": {
+ "operation": "operation:relation",
+ "operands": [
+ {
+ "wrap": {
+ "@type": "koral:term",
+ "layer": "c",
+ "foundry": "corenlp",
+ "match": "match:eq",
+ "key": "VP"
+ },
+ "@type": "koral:span"
+ },
+ {
+ "wrap": {
+ "@type": "koral:term",
+ "layer": "c",
+ "foundry": "corenlp",
+ "match": "match:eq",
+ "key": "NP"
+ },
+ "@type": "koral:span"
+ }
+ ],
+ "@type": "koral:group",
+ "relType": {
+ "@type": "koral:relation",
+ "wrap": {
+ "@type": "koral:term",
+ "layer": "d",
+ "foundry": "malt",
+ "match": "match:eq",
+ "type": "type:regex",
+ "key": ".*"
+ }
+ }
+ }
+}
\ No newline at end of file