Updates to collection queries
Change-Id: I8cdc07f9d6358ae29337c4b6fe5dd828d1efd1cc
diff --git a/Changes b/Changes
index 78efcbf..e9644b4 100644
--- a/Changes
+++ b/Changes
@@ -1,4 +1,4 @@
-0.52 2015-06-24
+0.52 2015-06-25
- [bugfix] Fixed payload filtering in FocusSpans (margaretha)
- [workaround] Reintroduced empty collection support,
as Koral still creates them (diewald)
@@ -10,6 +10,11 @@
- [bugfix] Mirror collection (diewald)
- [bugfix] Updated default fields for meta data (diewald)
- [bugfix] Updated match identifier for "sigle" data (diewald)
+ - [workaround] Support corpusID/docID and textSigle match strings
+ (diewald)
+ - [workaround] Support matches starting with "contains"
+ (Kustvakt bug/diewald)
+ - [bugfix] Fixed treatment of several collection types (diewald)
0.51 2015-03-17
- This is a major version (prepared for the GitHub release)
diff --git a/src/main/java/de/ids_mannheim/korap/KrillCollection.java b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
index 5d7d736..85a82f1 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillCollection.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
@@ -7,6 +7,7 @@
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.RegexFilter;
import de.ids_mannheim.korap.collection.FilterOperation;
import de.ids_mannheim.korap.collection.CollectionBuilder;
import de.ids_mannheim.korap.response.Notifications;
@@ -218,19 +219,54 @@
bfilter.till(dateStr);
break;
};
+
// No good reason for gt or lt
return bfilter;
}
+ // Filter based on string
else if (valtype.equals("type:string")) {
if (json.has("match"))
match = json.get("match").asText();
- if (match.equals("match:eq"))
+ if (match.equals("match:eq")) {
bfilter.and(key, json.get("value").asText());
+ }
+ else if (match.equals("match:ne")) {
+ bfilter.andNot(key, json.get("value").asText());
+ }
+ else {
+ // TODO!
+ throw new QueryException(0,"Unknown match type");
+ };
return bfilter;
+ }
+
+ // Filter based on regex
+ else if (valtype.equals("type:regex")) {
+ if (json.has("match"))
+ match = json.get("match").asText();
+
+ if (match.equals("match:eq")) {
+ return bfilter.and(
+ key,
+ new RegexFilter(json.get("value").asText())
+ );
+ }
+ else if (match.equals("match:ne")) {
+ return bfilter.andNot(
+ key,
+ new RegexFilter(json.get("value").asText())
+ );
+ };
+
+ // TODO! for excludes and contains
+ throw new QueryException(0,"Unknown document type");
};
+
+ // TODO!
+ throw new QueryException(0,"Unknown document operation");
}
// nested group
@@ -264,7 +300,7 @@
throw new QueryException(613,
"Collection query type has to be doc or docGroup");
- return new BooleanFilter();
+ // return new BooleanFilter();
};
diff --git a/src/main/java/de/ids_mannheim/korap/KrillIndex.java b/src/main/java/de/ids_mannheim/korap/KrillIndex.java
index 25dfd0d..b0120e7 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillIndex.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillIndex.java
@@ -815,10 +815,20 @@
// Create a filter based on the corpusID and the docID
BooleanQuery bool = new BooleanQuery();
- bool.add(new TermQuery(new Term("ID", match.getDocID())),
- BooleanClause.Occur.MUST);
- bool.add(new TermQuery(new Term("corpusID", match.getCorpusID())),
- BooleanClause.Occur.MUST);
+ if (match.getTextSigle() != null) {
+ bool.add(new TermQuery(
+ new Term("textSigle", match.getTextSigle())
+ ), BooleanClause.Occur.MUST);
+ }
+
+ // LEGACY
+ else {
+ bool.add(new TermQuery(new Term("ID", match.getDocID())),
+ BooleanClause.Occur.MUST);
+ bool.add(new TermQuery(new Term("corpusID", match.getCorpusID())),
+ BooleanClause.Occur.MUST);
+ };
+
Filter filter = (Filter) new QueryWrapperFilter(bool);
CompiledAutomaton fst = null;
@@ -839,6 +849,8 @@
if (includeSpans)
regex.append("((\">\"|\"<\"\">\")\":\")?");
+System.err.println("1 >>>>>>> " + regex);
+
// There is a foundry given
if (foundry != null && foundry.size() > 0) {
@@ -851,6 +863,8 @@
};
};
+System.err.println("2 >>>>>>> " + regex);
+
// Build regex for multiple foundries
if (foundry.size() > 0) {
regex.append("(");
@@ -874,6 +888,8 @@
};
};
+System.err.println("3 >>>>>>> " + regex);
+
// Build regex for multiple layers
if (layer.size() > 0) {
regex.append("(");
@@ -898,14 +914,21 @@
};
regex.append("(.){1,}|_[0-9]+");
+System.err.println("5 >>>>>>> " + regex);
+
if (DEBUG)
log.trace("The final regexString is {}", regex.toString());
+
+System.err.println("6 >>>>>>> " + regex.toString());
+
RegExp regexObj = new RegExp(regex.toString(), RegExp.COMPLEMENT);
fst = new CompiledAutomaton(regexObj.toAutomaton());
if (DEBUG)
log.trace("The final regexObj is {}", regexObj.toString());
};
+ System.err.println("++++++++++++++++++++++++++++++++++++++++++");
+
try {
// Iterate over all atomic indices and find the matching document
for (AtomicReaderContext atomic : this.reader().leaves()) {
diff --git a/src/main/java/de/ids_mannheim/korap/collection/BooleanFilter.java b/src/main/java/de/ids_mannheim/korap/collection/BooleanFilter.java
index 2f6853d..19693c6 100644
--- a/src/main/java/de/ids_mannheim/korap/collection/BooleanFilter.java
+++ b/src/main/java/de/ids_mannheim/korap/collection/BooleanFilter.java
@@ -20,7 +20,6 @@
/*
- Todo: !not
THIS IS LIMITED TO PUBDATE AT THE MOMENT AND COMPLETELY LEGACY!
*/
@@ -114,6 +113,33 @@
};
+ public BooleanFilter andNot (String type, String ... terms) {
+ for (String term : terms) {
+ bool.add(new TermQuery(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);
+ return this;
+ };
+
+
+ public BooleanFilter andNot (BooleanFilter bf) {
+ if (bf.bool.clauses().size() == 1) {
+ BooleanClause bc = bf.bool.getClauses()[0];
+ bc.setOccur(BooleanClause.Occur.MUST_NOT);
+ bool.add(bc);
+ return this;
+ }
+ bool.add(bf.toQuery(), BooleanClause.Occur.MUST_NOT);
+ return this;
+ };
+
+
public BooleanFilter since (String dateStr) {
int since = new KrillDate(dateStr).floor();
diff --git a/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java b/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
index bf5f243..234dded 100644
--- a/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
+++ b/src/main/java/de/ids_mannheim/korap/index/AbstractDocument.java
@@ -86,8 +86,12 @@
*/
@JsonProperty("pubDate")
public String getPubDateString () {
- if (this.pubDate != null)
- return this.pubDate.toDisplay();
+ if (this.pubDate != null) {
+ String date = this.pubDate.toDisplay();
+ if (date.length() == 0)
+ return null;
+ return date;
+ };
return null;
};
diff --git a/src/main/java/de/ids_mannheim/korap/response/Match.java b/src/main/java/de/ids_mannheim/korap/response/Match.java
index f68e389..3afc4e5 100644
--- a/src/main/java/de/ids_mannheim/korap/response/Match.java
+++ b/src/main/java/de/ids_mannheim/korap/response/Match.java
@@ -151,8 +151,15 @@
public Match (String idString, boolean includeHighlights) {
MatchIdentifier id = new MatchIdentifier(idString);
if (id.getStartPos() > -1) {
+
+ if (id.getTextSigle() != null)
+ this.setTextSigle(id.getTextSigle());
+
+ // <legacy>
this.setCorpusID(id.getCorpusID());
this.setDocID(id.getDocID());
+ // </legacy>
+
this.setStartPos(id.getStartPos());
this.setEndPos(id.getEndPos());
@@ -640,7 +647,7 @@
* @see MatchIdentifier
*/
@Override
- @JsonProperty("ID")
+ @JsonProperty("matchID")
public String getID () {
// Identifier already given
@@ -1429,6 +1436,8 @@
// Return match as token list
+ // TODO: This will be retrieved in case "tokenList" is
+ // requested in "fields"
public ObjectNode toTokenList () {
ObjectNode json = mapper.createObjectNode();
diff --git a/src/main/java/de/ids_mannheim/korap/response/Message.java b/src/main/java/de/ids_mannheim/korap/response/Message.java
index cef0150..f8f598b 100644
--- a/src/main/java/de/ids_mannheim/korap/response/Message.java
+++ b/src/main/java/de/ids_mannheim/korap/response/Message.java
@@ -21,6 +21,7 @@
* @author Nils Diewald
* @see de.ids_mannheim.korap.response.Messages
*/
+@JsonAutoDetect
public class Message implements Cloneable {
// Mapper for JSON serialization
ObjectMapper mapper = new ObjectMapper();
diff --git a/src/main/java/de/ids_mannheim/korap/response/SearchContext.java b/src/main/java/de/ids_mannheim/korap/response/SearchContext.java
index 91ebaa6..223fbd2 100644
--- a/src/main/java/de/ids_mannheim/korap/response/SearchContext.java
+++ b/src/main/java/de/ids_mannheim/korap/response/SearchContext.java
@@ -56,12 +56,14 @@
public SearchContext setSpanContext (String spanContext) {
this.spanType = true;
+ // <LEGACY>
if (spanContext.equals("sentence")) {
spanContext = "s";
}
else if (spanContext.equals("paragraph")) {
spanContext = "p";
};
+ // </LEGACY>
this.spanContext = spanContext;
return this;
diff --git a/src/main/java/de/ids_mannheim/korap/response/match/MatchIdentifier.java b/src/main/java/de/ids_mannheim/korap/response/match/MatchIdentifier.java
index b559b67..37a6c03 100644
--- a/src/main/java/de/ids_mannheim/korap/response/match/MatchIdentifier.java
+++ b/src/main/java/de/ids_mannheim/korap/response/match/MatchIdentifier.java
@@ -8,7 +8,8 @@
private ArrayList<int[]> pos = new ArrayList<>(8);
- Pattern idRegex = Pattern.compile("^match-(?:([^!]+?)[!\\.])?"
+ // TODO: "contains" is necessary for a compatibility bug in Kustvakt
+ Pattern idRegex = Pattern.compile("^(?:match-|contains-)(?:([^!]+?)[!\\.])?"
+ "([^!]+)-p([0-9]+)-([0-9]+)"
+ "((?:\\(-?[0-9]+\\)-?[0-9]+--?[0-9]+)*)" + "(?:c.+?)?$");
Pattern posRegex = Pattern.compile("\\(([0-9]+)\\)([0-9]+)-([0-9]+)");
@@ -18,13 +19,24 @@
public MatchIdentifier (String id) {
+
+ // Replace for legacy reasons with incompatible versions of Kustvakt
+ id = id.replaceAll("^(contains-|match-)([^-!_\\.]+?)!\\2_", "$1$2_");
+
Matcher matcher = idRegex.matcher(id);
if (matcher.matches()) {
- this.setCorpusID(matcher.group(1));
- this.setDocID(matcher.group(2));
- // TODO! FIXME!
- this.setTextSigle(this.getCorpusID() + "." + this.getDocID());
+ // <legacy>
+ // and test compatibility
+ if (id.contains("!") || !id.contains("_")) {
+ this.setCorpusID(matcher.group(1));
+ this.setDocID(matcher.group(2));
+ }
+ // </legacy>
+ else {
+ // this.getCorpusID() + "." + this.getDocID()
+ this.setTextSigle(matcher.group(1) + '.' + matcher.group(2));
+ };
this.setStartPos(Integer.parseInt(matcher.group(3)));
this.setEndPos(Integer.parseInt(matcher.group(4)));
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 41ce2dd..ba5a8f6 100644
--- a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionJSON.java
@@ -24,7 +24,6 @@
final String path = "/queries/collections/";
-
@Test
public void collection1 () {
String metaQuery = _getJSONString("collection_1.jsonld");
@@ -43,7 +42,6 @@
+ "[19900000 TO 99999999] +pubDate:[0 TO 20061099])); ");
};
-
@Test
public void collection3 () {
String metaQuery = _getJSONString("collection_3.jsonld");
@@ -61,6 +59,39 @@
};
+ @Test
+ public void collectionWithRegex () {
+ String query = _getJSONString("collection_7.jsonld");
+ Krill ks = new Krill(query);
+ assertFalse(ks.hasErrors());
+ assertFalse(ks.hasWarnings());
+ assertFalse(ks.hasMessages());
+ assertEquals("filter with QueryWrapperFilter(+author:/Goethe/); ", ks.getCollection().toString());
+ };
+
+
+ @Test
+ public void collectionWithNegativeRegex () {
+ String query = _getJSONString("collection_negregex.jsonld");
+ Krill ks = new Krill(query);
+ assertFalse(ks.hasErrors());
+ assertFalse(ks.hasWarnings());
+ assertFalse(ks.hasMessages());
+ assertEquals("filter with QueryWrapperFilter(-author:/Goethe/); ", ks.getCollection().toString());
+ };
+
+ @Test
+ public void collectionWithNegativeString () {
+ String query = _getJSONString("collection_ne.jsonld");
+ Krill ks = new Krill(query);
+ assertFalse(ks.hasErrors());
+ assertFalse(ks.hasWarnings());
+ assertFalse(ks.hasMessages());
+ assertEquals("filter with QueryWrapperFilter(-author:Goethe); ", ks.getCollection().toString());
+ };
+
+
+
@Ignore
public void nocollectiontypegiven () {
String metaQuery = _getJSONString("multiterm_rewrite_collection.jsonld");
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java b/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java
index a77a82b..9258455 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java
@@ -20,6 +20,9 @@
import de.ids_mannheim.korap.response.Match;
import de.ids_mannheim.korap.util.QueryException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.JsonNode;
+
import de.ids_mannheim.korap.index.FieldDocument;
@RunWith(JUnit4.class)
@@ -135,17 +138,15 @@
"... [{f/m:acht:b}{f/m:neun:a}] ...", km.getSnippetBrackets());
- /*
km = ki.getMatchInfo("match-c1!d1-p7-9(0)8-8(2)7-8",
"tokens",
"f",
null,
false,
false);
-
- System.err.println(km.toJSON());
- */
-
+ assertEquals("SnippetBrackets (1b)",
+ "... [{f/m:acht:{f/y:eight:b}}{f/m:neun:{f/y:nine:a}}] ...",
+ km.getSnippetBrackets());
km = ki.getMatchInfo("match-c1!d1-p7-9(0)8-8(2)7-8", "tokens", "f",
"m", false, true);
@@ -180,6 +181,16 @@
+ "</mark>" + "<span class=\"context-right\">"
+ "<span class=\"more\">" + "</span>" + "</span>",
km.getSnippetHTML());
+
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode res = mapper.readTree(km.toJsonString());
+ assertEquals("tokens", res.at("/field").asText());
+ assertTrue(res.at("/startMore").asBoolean());
+ assertTrue(res.at("/endMore").asBoolean());
+ assertEquals("c1", res.at("/corpusID").asText());
+ assertEquals("d1", res.at("/docID").asText());
+ assertEquals("match-c1!d1-p7-9(4)8-8(2)7-8", res.at("/matchID").asText());
+ assertTrue(res.at("/pubDate").isMissingNode());
};
diff --git a/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java b/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java
index 7f74b95..c43c77a 100644
--- a/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java
+++ b/src/test/java/de/ids_mannheim/korap/search/TestMetaFields.java
@@ -86,8 +86,8 @@
assertEquals("A", res.at("/matches/0/title").asText());
assertEquals("WPD_AAA.00001", res.at("/matches/0/docID").asText());
assertTrue(res.at("/matches/0/textSigle").isMissingNode());
- assertEquals("match-WPD_AAA.00001-p6-7", res.at("/matches/0/ID")
- .asText());
+ assertEquals("match-WPD_AAA.00001-p6-7", res.at("/matches/0/matchID").asText());
+ // assertEquals("p6-7", res.at("/matches/0/matchID").asText());
assertEquals("", res.at("/matches/0/subTitle").asText());
assertEquals("", res.at("/matches/0/textClass").asText());
assertEquals("", res.at("/matches/0/pubPlace").asText());
@@ -129,6 +129,9 @@
"base/s=spans cnx/c=spans cnx/l=tokens cnx/m=tokens cnx/p=tokens cnx/s=spans cnx/syn=tokens corenlp/c=spans corenlp/ne=tokens corenlp/p=tokens corenlp/s=spans glemm/l=tokens mate/l=tokens mate/m=tokens mate/p=tokens opennlp/p=tokens opennlp/s=spans tt/l=tokens tt/p=tokens tt/s=spans xip/c=spans xip/l=tokens xip/p=tokens xip/s=spans",
res.at("/matches/0/layerInfos").asText());
assertTrue(res.at("/matches/0/textType").isMissingNode());
+ assertEquals("match-GOE_AGX.00002-p7-8", res.at("/matches/0/matchID")
+ .asText());
+
// All fields
jsonString = getString(getClass().getResource(
@@ -157,7 +160,20 @@
res.at("/matches/0/docTitle").asText());
assertEquals("1827", res.at("/matches/0/creationDate").asText());
assertEquals("372-377", res.at("/matches/0/pages").asText());
- assertEquals("match-GOE_AGX.00002-p7-8", res.at("/matches/0/ID")
+ assertEquals("match-GOE_AGX.00002-p7-8", res.at("/matches/0/matchID")
.asText());
};
+
+
+ @Test
+ public void searchMetaContext () throws IOException {
+
+ // All fields
+ String jsonString = getString(getClass().getResource(
+ "/queries/metas/context_paragraph.jsonld").getFile());
+
+ Krill ks = new Krill(jsonString);
+ assertTrue(ks.getMeta().getContext().isSpanDefined());
+ assertEquals("base/p", ks.getMeta().getContext().getSpanContext());
+ };
};
diff --git a/src/test/java/de/ids_mannheim/korap/search/TestResult.java b/src/test/java/de/ids_mannheim/korap/search/TestResult.java
index 6d9a4d5..88e3240 100644
--- a/src/test/java/de/ids_mannheim/korap/search/TestResult.java
+++ b/src/test/java/de/ids_mannheim/korap/search/TestResult.java
@@ -75,7 +75,7 @@
*/
assertEquals(1, res.at("/matches/0/UID").asInt());
assertEquals("doc-1", res.at("/matches/0/docID").asText());
- assertEquals("match-doc-1-p0-1(1)0-0", res.at("/matches/0/ID").asText());
+ assertEquals("match-doc-1-p0-1(1)0-0", res.at("/matches/0/matchID").asText());
assertEquals(
"<span class=\"context-left\"></span><mark><mark class=\"class-1 level-0\">a</mark></mark><span class=\"context-right\">bab</span>",
res.at("/matches/0/snippet").asText());
@@ -88,7 +88,7 @@
*/
assertEquals(2, res.at("/matches/6/UID").asInt());
assertEquals("doc-2", res.at("/matches/6/docID").asText());
- assertEquals("match-doc-2-p2-3(1)2-2", res.at("/matches/6/ID").asText());
+ assertEquals("match-doc-2-p2-3(1)2-2", res.at("/matches/6/matchID").asText());
assertEquals(
"<span class=\"context-left\">ab</span><mark><mark class=\"class-1 level-0\">a</mark></mark><span class=\"context-right\"></span>",
res.at("/matches/6/snippet").asText());
@@ -195,7 +195,7 @@
// Matches
assertEquals(1, res.at("/matches/0/UID").asInt());
assertEquals("doc-1", res.at("/matches/0/docID").asText());
- assertEquals("match-doc-1-p0-1", res.at("/matches/0/ID").asText());
+ assertEquals("match-doc-1-p0-1", res.at("/matches/0/matchID").asText());
assertEquals(
"<span class=\"context-left\"></span><mark>a</mark><span class=\"context-right\">bab</span>",
res.at("/matches/0/snippet").asText());
diff --git a/src/test/resources/queries/collections/collection_7.jsonld b/src/test/resources/queries/collections/collection_7.jsonld
new file mode 100644
index 0000000..f78b14c
--- /dev/null
+++ b/src/test/resources/queries/collections/collection_7.jsonld
@@ -0,0 +1,26 @@
+{
+ "@context":"http://korap.ids-mannheim.de/ns/koral/0.3/context.jsonld",
+ "errors":[],
+ "warnings":[],
+ "messages":[],
+ "query":{
+ "@type":"koral:token",
+ "wrap":{
+ "@type":"koral:term",
+ "layer":"orth",
+ "key":"der",
+ "match":"match:eq",
+ "foundry":"opennlp"
+ }
+ },
+ "collection":{
+ "value":"Goethe",
+ "match":"match:eq",
+ "type":"type:regex",
+ "key":"author",
+ "@type":"koral:doc"
+ },
+ "meta":{
+ "cutOff":null
+ }
+}
diff --git a/src/test/resources/queries/collections/collection_8.jsonld b/src/test/resources/queries/collections/collection_8.jsonld
new file mode 100644
index 0000000..06ba1ab
--- /dev/null
+++ b/src/test/resources/queries/collections/collection_8.jsonld
@@ -0,0 +1,26 @@
+{
+ "@context":"http://korap.ids-mannheim.de/ns/koral/0.3/context.jsonld",
+ "errors":[],
+ "warnings":[],
+ "messages":[],
+ "query":{
+ "@type":"koral:token",
+ "wrap":{
+ "@type":"koral:term",
+ "layer":"orth",
+ "key":"der",
+ "match":"match:eq",
+ "foundry":"opennlp"
+ }
+ },
+ "collection":{
+ "value":"Goethe",
+ "match":"match:contains",
+ "type":"type:regex",
+ "key":"author",
+ "@type":"koral:doc"
+ },
+ "meta":{
+ "cutOff":null
+ }
+}
diff --git a/src/test/resources/queries/collections/collection_ne.jsonld b/src/test/resources/queries/collections/collection_ne.jsonld
new file mode 100644
index 0000000..f9b0e79
--- /dev/null
+++ b/src/test/resources/queries/collections/collection_ne.jsonld
@@ -0,0 +1,26 @@
+{
+ "@context":"http://korap.ids-mannheim.de/ns/koral/0.3/context.jsonld",
+ "errors":[],
+ "warnings":[],
+ "messages":[],
+ "query":{
+ "@type":"koral:token",
+ "wrap":{
+ "@type":"koral:term",
+ "layer":"orth",
+ "key":"der",
+ "match":"match:eq",
+ "foundry":"opennlp"
+ }
+ },
+ "collection":{
+ "value":"Goethe",
+ "match":"match:ne",
+ "type":"type:string",
+ "key":"author",
+ "@type":"koral:doc"
+ },
+ "meta":{
+ "cutOff":null
+ }
+}
diff --git a/src/test/resources/queries/collections/collection_negregex.jsonld b/src/test/resources/queries/collections/collection_negregex.jsonld
new file mode 100644
index 0000000..fe1ecc3
--- /dev/null
+++ b/src/test/resources/queries/collections/collection_negregex.jsonld
@@ -0,0 +1,26 @@
+{
+ "@context":"http://korap.ids-mannheim.de/ns/koral/0.3/context.jsonld",
+ "errors":[],
+ "warnings":[],
+ "messages":[],
+ "query":{
+ "@type":"koral:token",
+ "wrap":{
+ "@type":"koral:term",
+ "layer":"orth",
+ "key":"der",
+ "match":"match:eq",
+ "foundry":"opennlp"
+ }
+ },
+ "collection":{
+ "value":"Goethe",
+ "match":"match:ne",
+ "type":"type:regex",
+ "key":"author",
+ "@type":"koral:doc"
+ },
+ "meta":{
+ "cutOff":null
+ }
+}
diff --git a/src/test/resources/queries/metas/context_paragraph.jsonld b/src/test/resources/queries/metas/context_paragraph.jsonld
new file mode 100644
index 0000000..7a5e7f3
--- /dev/null
+++ b/src/test/resources/queries/metas/context_paragraph.jsonld
@@ -0,0 +1 @@
+{"@context":"http://korap.ids-mannheim.de/ns/koral/0.3/context.jsonld","errors":[],"warnings":[],"messages":[],"collection":{},"query":{"@type":"koral:token","wrap":{"@type":"koral:term","layer":"orth","key":"frage","match":"match:eq","flags":["flags:caseInsensitive"],"foundry":"opennlp"}},"meta":{"startPage":1,"count":25,"cutOff":true,"context":"base/p"}}
\ No newline at end of file