Try to fix collections ... didn't work as expected
Change-Id: I8980d666b0df00b097a62e2e3dd2620a0d17da34
diff --git a/src/main/java/de/ids_mannheim/korap/KrillCollection.java b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
index a89fdfc..1edfb64 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillCollection.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
@@ -6,7 +6,7 @@
import de.ids_mannheim.korap.*;
import de.ids_mannheim.korap.util.KrillDate;
import de.ids_mannheim.korap.util.QueryException;
-import de.ids_mannheim.korap.collection.BooleanFilter;
+import de.ids_mannheim.korap.collection.BooleanFilterOperation;
import de.ids_mannheim.korap.collection.RegexFilter;
import de.ids_mannheim.korap.collection.FilterOperation;
import de.ids_mannheim.korap.collection.CollectionBuilder;
@@ -46,6 +46,7 @@
* @author diewald
*/
/*
+ * TODO: Use CachingWrapperFilter!!!
* TODO: Clean up for new KoralQuery
* TODO: Make a cache for the bits
* Delete it in case of an extension or a filter
@@ -167,15 +168,15 @@
// Create a boolean filter from JSON
- private BooleanFilter _fromJson (JsonNode json) throws QueryException {
+ private BooleanFilterOperation _fromJson (JsonNode json) throws QueryException {
return this._fromJson(json, "tokens");
};
// Create a booleanfilter from JSON
- private BooleanFilter _fromJson (JsonNode json, String field)
+ private BooleanFilterOperation _fromJson (JsonNode json, String field)
throws QueryException {
- BooleanFilter bfilter = new BooleanFilter();
+ BooleanFilterOperation bfilter = new BooleanFilterOperation();
if (!json.has("@type")) {
throw new QueryException(701,
@@ -285,7 +286,7 @@
if (json.has("operation"))
operation = json.get("operation").asText();
- BooleanFilter group = new BooleanFilter();
+ BooleanFilterOperation group = new BooleanFilterOperation();
for (JsonNode operand : json.get("operands")) {
if (operation.equals("operation:and"))
@@ -307,7 +308,7 @@
throw new QueryException(613,
"Collection query type has to be doc or docGroup");
- // return new BooleanFilter();
+ // return new BooleanFilterOperation();
};
@@ -352,7 +353,7 @@
if (!json.has("@value"))
throw new QueryException(851, "Legacy filter need @value fields");
- BooleanFilter bf = this._fromJsonLegacy(json.get("@value"), "tokens");
+ BooleanFilterOperation bf = this._fromJsonLegacy(json.get("@value"), "tokens");
String type = json.get("@type").asText();
// Filter the collection
@@ -375,9 +376,9 @@
// Create a boolean filter from a Json string
@Deprecated
- private BooleanFilter _fromJsonLegacy (JsonNode json, String field)
+ private BooleanFilterOperation _fromJsonLegacy (JsonNode json, String field)
throws QueryException {
- BooleanFilter bfilter = new BooleanFilter();
+ BooleanFilterOperation bfilter = new BooleanFilterOperation();
if (!json.has("@type"))
throw new QueryException(612,
@@ -412,7 +413,7 @@
if (DEBUG)
log.trace("relation found {}", json.get("relation").asText());
- BooleanFilter group = new BooleanFilter();
+ BooleanFilterOperation group = new BooleanFilterOperation();
switch (json.get("relation").asText()) {
case "between":
@@ -489,7 +490,7 @@
/**
- * Add a filter by means of a {@link BooleanFilter}.
+ * Add a filter by means of a {@link BooleanFilterOperation}.
*
* <strong>Warning</strong>: Filters are part of the collections
* legacy API and may vanish without warning.
@@ -499,7 +500,7 @@
* @return The {@link KrillCollection} object for chaining.
*/
// TODO: The checks may not be necessary
- public KrillCollection filter (BooleanFilter filter) {
+ public KrillCollection filter (BooleanFilterOperation filter) {
if (DEBUG)
log.trace("Added filter: {}", filter.toString());
@@ -535,12 +536,12 @@
* @return The {@link KrillCollection} object for chaining.
*/
public KrillCollection filter (CollectionBuilder filter) {
- return this.filter(filter.getBooleanFilter());
+ return this.filter(filter.getBooleanFilterOperation());
};
/**
- * Add an extension by means of a {@link BooleanFilter}.
+ * Add an extension by means of a {@link BooleanFilterOperation}.
*
* <strong>Warning</strong>: Extensions are part of the
* collections
@@ -550,7 +551,7 @@
* The extension to add to the collection.
* @return The {@link KrillCollection} object for chaining.
*/
- public KrillCollection extend (BooleanFilter extension) {
+ public KrillCollection extend (BooleanFilterOperation extension) {
if (DEBUG)
log.trace("Added extension: {}", extension.toString());
@@ -574,7 +575,7 @@
* @return The {@link KrillCollection} object for chaining.
*/
public KrillCollection extend (CollectionBuilder extension) {
- return this.extend(extension.getBooleanFilter());
+ return this.extend(extension.getBooleanFilterOperation());
};
@@ -589,7 +590,7 @@
* @return The {@link KrillCollection} object for chaining.
*/
public KrillCollection filterUIDs (String ... uids) {
- BooleanFilter filter = new BooleanFilter();
+ BooleanFilterOperation filter = new BooleanFilterOperation();
filter.or("UID", uids);
if (DEBUG)
log.debug("UID based filter: {}", filter.toString());
@@ -721,7 +722,7 @@
FilterOperation kcInit = filters.remove(0);
if (DEBUG)
- log.trace("FILTER: {}", kcInit);
+ log.trace("FILTER: {}", kcInit.filter.toString());
// Init vector
DocIdSet docids = kcInit.filter.getDocIdSet(atomic, null);
@@ -734,6 +735,9 @@
log.trace("InitFilter has effect");
bitset.or(filterIter);
noDoc = false;
+ }
+ else if (DEBUG) {
+ log.trace("InitFilter has no effect");
};
// Apply all filters sequentially
diff --git a/src/main/java/de/ids_mannheim/korap/collection/BooleanFilter.java b/src/main/java/de/ids_mannheim/korap/collection/BooleanFilterOperation.java
similarity index 65%
rename from src/main/java/de/ids_mannheim/korap/collection/BooleanFilter.java
rename to src/main/java/de/ids_mannheim/korap/collection/BooleanFilterOperation.java
index 19693c6..f5ab6e1 100644
--- a/src/main/java/de/ids_mannheim/korap/collection/BooleanFilter.java
+++ b/src/main/java/de/ids_mannheim/korap/collection/BooleanFilterOperation.java
@@ -5,12 +5,17 @@
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.queries.BooleanFilter;
+import org.apache.lucene.queries.TermFilter;
+import org.apache.lucene.queries.FilterClause;
import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.RegexpQuery;
import org.apache.lucene.search.NumericRangeQuery;
+// Temporary
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.BooleanQuery;
+
import de.ids_mannheim.korap.util.KrillDate;
import de.ids_mannheim.korap.KrillCollection;
import de.ids_mannheim.korap.util.QueryException;
@@ -20,17 +25,17 @@
/*
- THIS IS LIMITED TO PUBDATE AT THE MOMENT AND COMPLETELY LEGACY!
-*/
+ * THIS IS LIMITED TO PUBDATE AT THE MOMENT AND COMPLETELY LEGACY!
+ */
/**
* @author Nils Diewald
*
- * BooleanFilter implements a simple API for boolean
+ * BooleanFilterOperation implements a simple API for boolean
* operations
* on constraints for KorapFilter.
*/
-public class BooleanFilter {
+public class BooleanFilterOperation {
private String type;
// Logger
@@ -40,107 +45,107 @@
// This advices the java compiler to ignore all loggings
public static final boolean DEBUG = false;
- private BooleanQuery bool;
+ private BooleanFilter bool;
private String error;
- public BooleanFilter () {
- bool = new BooleanQuery();
+ public BooleanFilterOperation () {
+ bool = new BooleanFilter();
};
- public BooleanFilter or (String type, String ... terms) {
+ public BooleanFilterOperation or (String type, String ... terms) {
for (String term : terms) {
if (DEBUG)
log.trace("Filter: OR {}={}", type, term);
- bool.add(new TermQuery(new Term(type, term)),
+ bool.add(new TermFilter(new Term(type, term)),
BooleanClause.Occur.SHOULD);
};
return this;
};
- public BooleanFilter or (String type, RegexFilter value) {
- bool.add(value.toQuery(type), BooleanClause.Occur.SHOULD);
+ public BooleanFilterOperation or (String type, RegexFilter value) {
+ bool.add(value.toFilter(type), BooleanClause.Occur.SHOULD);
return this;
};
- public BooleanFilter or (BooleanFilter bf) {
+ public BooleanFilterOperation or (BooleanFilterOperation bf) {
if (bf.bool.clauses().size() == 1) {
- BooleanClause bc = bf.bool.getClauses()[0];
+ FilterClause bc = bf.bool.clauses().get(0);
bc.setOccur(BooleanClause.Occur.SHOULD);
bool.add(bc);
return this;
}
- bool.add(bf.toQuery(), BooleanClause.Occur.SHOULD);
+ bool.add(bf.toFilter(), BooleanClause.Occur.SHOULD);
return this;
};
- public BooleanFilter or (NumericRangeQuery<Integer> nrq) {
+ public BooleanFilterOperation or (NumericRangeQuery<Integer> nrq) {
bool.add(nrq, BooleanClause.Occur.SHOULD);
return this;
};
- public BooleanFilter and (String type, String ... terms) {
+ public BooleanFilterOperation and (String type, String ... terms) {
for (String term : terms) {
- bool.add(new TermQuery(new Term(type, term)),
+ bool.add(new TermFilter(new Term(type, term)),
BooleanClause.Occur.MUST);
};
return this;
};
- public BooleanFilter and (String type, RegexFilter value) {
- bool.add(value.toQuery(type), BooleanClause.Occur.MUST);
+ public BooleanFilterOperation and (String type, RegexFilter value) {
+ bool.add(value.toFilter(type), BooleanClause.Occur.MUST);
return this;
};
- public BooleanFilter and (BooleanFilter bf) {
+ public BooleanFilterOperation and (BooleanFilterOperation bf) {
if (bf.bool.clauses().size() == 1) {
- BooleanClause bc = bf.bool.getClauses()[0];
+ FilterClause bc = bf.bool.clauses().get(0);
bc.setOccur(BooleanClause.Occur.MUST);
bool.add(bc);
return this;
}
- bool.add(bf.toQuery(), BooleanClause.Occur.MUST);
+ bool.add(bf.toFilter(), BooleanClause.Occur.MUST);
return this;
};
- public BooleanFilter andNot (String type, String ... terms) {
+ public BooleanFilterOperation andNot (String type, String ... terms) {
for (String term : terms) {
- bool.add(new TermQuery(new Term(type, term)),
+ bool.add(new TermFilter(new Term(type, term)),
BooleanClause.Occur.MUST_NOT);
};
return this;
};
- public BooleanFilter andNot (String type, RegexFilter value) {
- bool.add(value.toQuery(type), BooleanClause.Occur.MUST_NOT);
+ public BooleanFilterOperation andNot (String type, RegexFilter value) {
+ bool.add(value.toFilter(type), BooleanClause.Occur.MUST_NOT);
return this;
};
- public BooleanFilter andNot (BooleanFilter bf) {
+ public BooleanFilterOperation andNot (BooleanFilterOperation bf) {
if (bf.bool.clauses().size() == 1) {
- BooleanClause bc = bf.bool.getClauses()[0];
+ FilterClause bc = bf.bool.clauses().get(0);
bc.setOccur(BooleanClause.Occur.MUST_NOT);
bool.add(bc);
return this;
}
- bool.add(bf.toQuery(), BooleanClause.Occur.MUST_NOT);
+ bool.add(bf.toFilter(), BooleanClause.Occur.MUST_NOT);
return this;
};
- public BooleanFilter since (String dateStr) {
+ public BooleanFilterOperation since (String dateStr) {
int since = new KrillDate(dateStr).floor();
if (since == 0 || since == KrillDate.BEGINNING)
@@ -153,7 +158,7 @@
};
- public BooleanFilter till (String dateStr) {
+ public BooleanFilterOperation till (String dateStr) {
try {
int till = new KrillDate(dateStr).ceil();
if (till == 0 || till == KrillDate.END)
@@ -170,7 +175,7 @@
};
- public BooleanFilter between (String beginStr, String endStr) {
+ public BooleanFilterOperation between (String beginStr, String endStr) {
KrillDate beginDF = new KrillDate(beginStr);
int begin = beginDF.floor();
@@ -194,7 +199,7 @@
};
- public BooleanFilter date (String dateStr) {
+ public BooleanFilterOperation date (String dateStr) {
KrillDate dateDF = new KrillDate(dateStr);
if (dateDF.year == 0)
@@ -217,11 +222,14 @@
return this;
};
-
+ @Deprecated
public Query toQuery () {
return this.bool;
};
+ public Query toFilter () {
+ return this.bool;
+ };
public String toString () {
return this.bool.toString();
diff --git a/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java b/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java
index 809165f..6ee2119 100644
--- a/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java
+++ b/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java
@@ -1,6 +1,6 @@
package de.ids_mannheim.korap.collection;
-import de.ids_mannheim.korap.collection.BooleanFilter;
+import de.ids_mannheim.korap.collection.BooleanFilterOperation;
import de.ids_mannheim.korap.collection.RegexFilter;
import de.ids_mannheim.korap.util.QueryException;
import de.ids_mannheim.korap.util.KrillDate;
@@ -27,7 +27,7 @@
* Todo: Supports foundries
*/
public class CollectionBuilder {
- private BooleanFilter filter;
+ private BooleanFilterOperation filter;
private String field = "tokens";
// Logger
@@ -42,61 +42,61 @@
* Construct a new CollectionBuilder object.
*/
public CollectionBuilder () {
- filter = new BooleanFilter();
+ filter = new BooleanFilterOperation();
};
- public BooleanFilter and (String type, String ... terms) {
- BooleanFilter bf = new BooleanFilter();
+ public BooleanFilterOperation and (String type, String ... terms) {
+ BooleanFilterOperation bf = new BooleanFilterOperation();
bf.and(type, terms);
return bf;
};
- public BooleanFilter or (String type, String ... terms) {
- BooleanFilter bf = new BooleanFilter();
+ public BooleanFilterOperation or (String type, String ... terms) {
+ BooleanFilterOperation bf = new BooleanFilterOperation();
bf.or(type, terms);
return bf;
};
- public BooleanFilter and (String type, RegexFilter re) {
- BooleanFilter bf = new BooleanFilter();
+ public BooleanFilterOperation and (String type, RegexFilter re) {
+ BooleanFilterOperation bf = new BooleanFilterOperation();
bf.and(type, re);
return bf;
};
- public BooleanFilter or (String type, RegexFilter re) {
- BooleanFilter bf = new BooleanFilter();
+ public BooleanFilterOperation or (String type, RegexFilter re) {
+ BooleanFilterOperation bf = new BooleanFilterOperation();
bf.or(type, re);
return bf;
};
- public BooleanFilter since (String date) {
- BooleanFilter bf = new BooleanFilter();
+ public BooleanFilterOperation since (String date) {
+ BooleanFilterOperation bf = new BooleanFilterOperation();
bf.since(date);
return bf;
};
- public BooleanFilter till (String date) {
- BooleanFilter bf = new BooleanFilter();
+ public BooleanFilterOperation till (String date) {
+ BooleanFilterOperation bf = new BooleanFilterOperation();
bf.till(date);
return bf;
};
- public BooleanFilter date (String date) {
- BooleanFilter bf = new BooleanFilter();
+ public BooleanFilterOperation date (String date) {
+ BooleanFilterOperation bf = new BooleanFilterOperation();
bf.date(date);
return bf;
};
- public BooleanFilter between (String date1, String date2) {
- BooleanFilter bf = new BooleanFilter();
+ public BooleanFilterOperation between (String date1, String date2) {
+ BooleanFilterOperation bf = new BooleanFilterOperation();
bf.between(date1, date2);
return bf;
};
@@ -107,12 +107,12 @@
};
- public BooleanFilter getBooleanFilter () {
+ public BooleanFilterOperation getBooleanFilterOperation () {
return this.filter;
};
- public void setBooleanFilter (BooleanFilter bf) {
+ public void setBooleanFilterOperation (BooleanFilterOperation bf) {
this.filter = bf;
};
diff --git a/src/main/java/de/ids_mannheim/korap/collection/RegexFilter.java b/src/main/java/de/ids_mannheim/korap/collection/RegexFilter.java
index c948dab..781360a 100644
--- a/src/main/java/de/ids_mannheim/korap/collection/RegexFilter.java
+++ b/src/main/java/de/ids_mannheim/korap/collection/RegexFilter.java
@@ -4,6 +4,8 @@
import org.apache.lucene.search.RegexpQuery;
import org.apache.lucene.index.Term;
+import org.apache.lucene.search.QueryWrapperFilter;
+import org.apache.lucene.search.Filter;
/**
* @author Nils Diewald
@@ -21,8 +23,15 @@
this.regex = regex;
};
-
+ @Deprecated
public RegexpQuery toQuery (String field) {
return new RegexpQuery(new Term(field, this.regex));
};
+
+ public Filter toFilter (String field) {
+ return new QueryWrapperFilter(
+ new RegexpQuery(new Term(field, this.regex))
+ );
+ };
+
};
diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties
index 5fed33b..eacf929 100644
--- a/src/main/resources/log4j.properties
+++ b/src/main/resources/log4j.properties
@@ -1,4 +1,4 @@
-log4j.rootLogger = ERROR, stdout
+# log4j.rootLogger = ERROR, stdout
# Queries:
# log4j.logger.de.ids_mannheim.korap.query.SpanNextQuery = TRACE, stdout
@@ -21,7 +21,7 @@
# Collections:
# log4j.logger.de.ids_mannheim.korap.collection.Filter = TRACE, stdout
-# log4j.logger.de.ids_mannheim.korap.KrillCollection = TRACE, stdout
+log4j.logger.de.ids_mannheim.korap.KrillCollection = TRACE, stdout
# Responses:
# log4j.logger.de.ids_mannheim.korap.server.Node = TRACE, stdout
diff --git a/src/test/java/de/ids_mannheim/korap/benchmark/TestBenchmarkSpans.java b/src/test/java/de/ids_mannheim/korap/benchmark/TestBenchmarkSpans.java
index 4f7ba16..922792e 100644
--- a/src/test/java/de/ids_mannheim/korap/benchmark/TestBenchmarkSpans.java
+++ b/src/test/java/de/ids_mannheim/korap/benchmark/TestBenchmarkSpans.java
@@ -11,7 +11,6 @@
import de.ids_mannheim.korap.KrillQuery;
import de.ids_mannheim.korap.query.QueryBuilder;
import org.apache.lucene.store.MMapDirectory;
-import de.ids_mannheim.korap.collection.BooleanFilter;
import org.apache.lucene.search.spans.SpanQuery;
import de.ids_mannheim.korap.query.wrap.SpanQueryWrapper;
import de.ids_mannheim.korap.util.QueryException;
diff --git a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionJSON.java b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionJSON.java
index cbc60bc..df70026 100644
--- a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionJSON.java
@@ -127,6 +127,7 @@
};
ki.commit();
+ // No collection
Krill krill = new Krill(_getJSONString("collection_6.jsonld"));
Result kr = krill.apply(ki);
assertEquals(kr.getTotalResults(), 86);
@@ -135,6 +136,7 @@
JsonNode res = mapper.readTree(kr.toJsonString());
assertTrue(res.at("/collection").isMissingNode());
+ // textClass = reisen
krill = new Krill(_getJSONString("collection_6_withCollection.jsonld"));
kr = krill.apply(ki);
@@ -145,7 +147,13 @@
assertEquals("koral:doc", res.at("/collection/@type").asText());
assertEquals("textClass", res.at("/collection/key").asText());
assertEquals("reisen", res.at("/collection/value").asText());
- assertEquals("match:eq", res.at("/collection/match").asText());
+ assertEquals("match:contains", res.at("/collection/match").asText());
+
+ // textClass = reisen
+ krill = new Krill(_getJSONString("collection_6_withNegativeCollection.jsonld"));
+
+ kr = krill.apply(ki);
+ assertEquals(86 - 57, kr.getTotalResults());
};
diff --git a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionLegacy.java b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionLegacy.java
index 8341c1c..f38d8bb 100644
--- a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionLegacy.java
+++ b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionLegacy.java
@@ -8,7 +8,7 @@
import de.ids_mannheim.korap.response.Result;
import de.ids_mannheim.korap.KrillQuery;
import de.ids_mannheim.korap.query.QueryBuilder;
-import de.ids_mannheim.korap.collection.BooleanFilter;
+import de.ids_mannheim.korap.collection.BooleanFilterOperation;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.spans.SpanOrQuery;
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestWPDIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestWPDIndex.java
index 1b1ef4d..d5f823c 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestWPDIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestWPDIndex.java
@@ -18,7 +18,7 @@
import de.ids_mannheim.korap.response.Match;
import de.ids_mannheim.korap.response.Result;
import de.ids_mannheim.korap.Krill;
-import de.ids_mannheim.korap.collection.BooleanFilter;
+import de.ids_mannheim.korap.collection.BooleanFilterOperation;
import de.ids_mannheim.korap.query.DistanceConstraint;
import de.ids_mannheim.korap.query.SpanDistanceQuery;
import de.ids_mannheim.korap.query.SpanElementQuery;
@@ -167,7 +167,7 @@
//0.8s
// Check if it includes some results
- BooleanFilter bf = new BooleanFilter();
+ BooleanFilterOperation bf = new BooleanFilterOperation();
bf.or("ID", "WPD_BBB.04463", "WPD_III.00758");
KrillCollection kc = new KrillCollection();
kc.filter(bf);
diff --git a/src/test/resources/queries/collections/collection_6_withCollection.jsonld b/src/test/resources/queries/collections/collection_6_withCollection.jsonld
index 91d960a..f3edb11 100644
--- a/src/test/resources/queries/collections/collection_6_withCollection.jsonld
+++ b/src/test/resources/queries/collections/collection_6_withCollection.jsonld
@@ -7,7 +7,7 @@
"@type":"koral:doc",
"key":"textClass",
"value":"reisen",
- "match":"match:eq"
+ "match":"match:contains"
},
"query":{
"@type":"koral:token",
diff --git a/src/test/resources/queries/collections/collection_6_withNegativeCollection.jsonld b/src/test/resources/queries/collections/collection_6_withNegativeCollection.jsonld
new file mode 100644
index 0000000..ba2347f
--- /dev/null
+++ b/src/test/resources/queries/collections/collection_6_withNegativeCollection.jsonld
@@ -0,0 +1,25 @@
+{
+ "@context":"http://korap.ids-mannheim.de/ns/koral/0.3/context.jsonld",
+ "errors":[],
+ "warnings":[],
+ "messages":[],
+ "collection":{
+ "@type":"koral:doc",
+ "key":"textClass",
+ "value":"reisen",
+ "match":"match:containsnot"
+ },
+ "query":{
+ "@type":"koral:token",
+ "wrap":{
+ "@type":"koral:term",
+ "layer":"orth",
+ "key":"der",
+ "match":"match:eq",
+ "foundry":"opennlp"
+ }
+ },
+ "meta":{
+ "cutOff":null
+ }
+}