Implemented relation queries with regex.
Change-Id: I1dafc835f6034d90a350d9688acdcf54bac28124
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