Adopted more legacy tests and removed search API from collections

Change-Id: I30d544b3f09b2b4971e2c39e793894498a62778e
diff --git a/src/main/java/de/ids_mannheim/korap/KrillCollection.java b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
index 329550f..943819c 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillCollection.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillCollection.java
@@ -47,7 +47,8 @@
 public class KrillCollection extends Notifications {
     private KrillIndex index;
     private JsonNode json;
-    private CollectionBuilder.CollectionBuilderInterface cb;
+    private CollectionBuilder cb = new CollectionBuilder();
+    private CollectionBuilder.CollectionBuilderInterface cbi;
     private byte[] pl = new byte[4];
     private static ByteBuffer bb = ByteBuffer.allocate(4);
 
@@ -156,8 +157,6 @@
 
     private CollectionBuilder.CollectionBuilderInterface _fromJson (JsonNode json) throws QueryException {
 
-        CollectionBuilder cb = new CollectionBuilder();
-
         if (!json.has("@type")) {
             throw new QueryException(701,
                     "JSON-LD group has no @type attribute");
@@ -191,13 +190,13 @@
                 // TODO: This isn't stable yet
                 switch (match) {
                 case "match:eq":
-                    return cb.date(key, dateStr);
+                    return this.cb.date(key, dateStr);
                 case "match:ne":
-                    return cb.date(key, dateStr).not();
+                    return this.cb.date(key, dateStr).not();
                 case "match:geq":
-                    return cb.since(key, dateStr);
+                    return this.cb.since(key, dateStr);
                 case "match:leq":
-                    return cb.till(key, dateStr);
+                    return this.cb.till(key, dateStr);
                 };
 
                 throw new QueryException(841, "Match relation unknown for type");
@@ -211,20 +210,20 @@
                 switch (match) {
 
                 case "match:eq":
-                    return cb.term(key, json.get("value").asText());
+                    return this.cb.term(key, json.get("value").asText());
                 case "match:ne":
-                    return cb.term(key, json.get("value").asText()).not();
+                    return this.cb.term(key, json.get("value").asText()).not();
 
                 // This may change - but for now it means the elements are lowercased
                 case "match:contains":
-                    return cb.term(key, json.get("value").asText().toLowerCase());
+                    return this.cb.term(key, json.get("value").asText().toLowerCase());
 
                 case "match:containsnot":
-                    return cb.term(key, json.get("value").asText().toLowerCase()).not();
+                    return this.cb.term(key, json.get("value").asText().toLowerCase()).not();
 
                     // <LEGACY>
                 case "match:excludes":
-                    return cb.term(key, json.get("value").asText().toLowerCase()).not();
+                    return this.cb.term(key, json.get("value").asText().toLowerCase()).not();
                     // </LEGACY>
                 };
 
@@ -238,16 +237,16 @@
                     match = json.get("match").asText();
 
                 if (match.equals("match:eq")) {
-                    return cb.re(key, json.get("value").asText());
+                    return this.cb.re(key, json.get("value").asText());
                 }
                 else if (match.equals("match:ne")) {
-                    return cb.re(key, json.get("value").asText()).not();
+                    return this.cb.re(key, json.get("value").asText()).not();
                 }
                 else if (match.equals("match:contains")) {
-                    return cb.re(key, json.get("value").asText());
+                    return this.cb.re(key, json.get("value").asText());
                 }
                 else if (match.equals("match:excludes")) {
-                    return cb.re(key, json.get("value").asText()).not();
+                    return this.cb.re(key, json.get("value").asText()).not();
                 };
 
                 throw new QueryException(841, "Match relation unknown for type");
@@ -269,9 +268,9 @@
                 operation = json.get("operation").asText();            
 
             if (operation.equals("operation:or"))
-                group = cb.orGroup();
+                group = this.cb.orGroup();
             else if (operation.equals("operation:and"))
-                group = cb.andGroup();
+                group = this.cb.andGroup();
             else
                 throw new QueryException(810, "Unknown document group operation");
     
@@ -292,23 +291,35 @@
     };
 
 
-
-
-
     /**
      * Set the collection from a {@link CollectionBuilder} object.
      * 
      * @param cb The CollectionBuilder object.
      */
-    public KrillCollection fromBuilder (CollectionBuilder.CollectionBuilderInterface cb) {
-        this.cb = cb;
+    public KrillCollection fromBuilder (CollectionBuilder.CollectionBuilderInterface cbi) {
+        this.cbi = cbi;
         return this;
     };
 
     public CollectionBuilder.CollectionBuilderInterface getBuilder () {
+        return this.cbi;
+    };
+
+
+    public CollectionBuilder build () {
         return this.cb;
     };
 
+    public KrillCollection filter (CollectionBuilder.CollectionBuilderInterface filter) {
+        return this.fromBuilder(this.cb.andGroup().with(this.cbi).with(filter));
+    };
+
+    public KrillCollection extend (CollectionBuilder.CollectionBuilderInterface extension) {
+        return this.fromBuilder(this.cb.orGroup().with(this.cbi).with(extension));
+    };
+
+
+
     /**
      * Add a filter based on a list of unique document identifiers.
      * UIDs may be indexed in the field "UID".
@@ -320,6 +331,18 @@
      * @return The {@link KrillCollection} object for chaining.
      */
     public KrillCollection filterUIDs (String ... uids) {
+        CollectionBuilder.CollectionBuilderInterface root = this.getBuilder();
+        CollectionBuilder.CollectionBuilderGroup cbg = this.cb.orGroup();
+        CollectionBuilder.CollectionBuilderGroup filter = this.cb.andGroup();
+        for (String uid : uids) {
+            cbg.with(this.cb.term("UID", uid));
+        };
+        if (this.getBuilder() != null)
+            filter.with(this.getBuilder());
+        filter.with(cbg);
+
+        this.fromBuilder(filter);
+
         /*
         BooleanFilter filter = new BooleanFilter();
         filter.or("UID", uids);
@@ -335,10 +358,10 @@
      * Serialize collection to a {@link Filter} object.
      */
     public Filter toFilter () {
-        if (this.cb == null)
+        if (this.cbi == null)
             return null;
 
-        return this.cb.toFilter();
+        return this.cbi.toFilter();
     };
 
 
@@ -347,10 +370,10 @@
      * not.
      */
     public boolean isNegative () {
-        if (this.cb == null)
+        if (this.cbi == null)
             return false;
 
-        return this.cb.isNegative();
+        return this.cbi.isNegative();
     };
 
 
@@ -387,27 +410,6 @@
     };
 
 
-
-    /**
-     * Search in the virtual collection.
-     * This is mostly used for testing purposes
-     * and <strong>is not recommended</strong>
-     * as a common search API.
-     * 
-     * Please use {@link KrillQuery#run} instead.
-     * 
-     * @param query
-     *            a {@link SpanQuery} to apply on the
-     *            virtual collection.
-     * @return A {@link Result} object representing the search's
-     *         result.
-     */
-    public Result search (SpanQuery query) {
-        // return this.index.search(this, query, 0, (short) 20, true, (short) 5, true, (short) 5);
-        return null;
-    };
-
-
     /**
      * Create a bit vector representing the live documents of the
      * virtual collection to be used in searches.
@@ -449,7 +451,7 @@
         FixedBitSet bitset = new FixedBitSet(maxDoc);
 
         Filter filter;
-        if (this.cb == null || (filter = this.cb.toFilter()) == null)
+        if (this.cbi == null || (filter = this.cbi.toFilter()) == null)
             return null;
 
         // Init vector
@@ -457,7 +459,7 @@
         DocIdSetIterator filterIter = (docids == null) ? null : docids.iterator();
 
         if (filterIter == null) {
-            if (!this.cb.isNegative())
+            if (!this.cbi.isNegative())
                 return null;
 
             bitset.set(0, maxDoc);
@@ -467,7 +469,7 @@
             bitset.or(filterIter);
 
             // Revert for negation
-            if (this.cb.isNegative())
+            if (this.cbi.isNegative())
                 bitset.flip(0, maxDoc);
         };
 
@@ -506,8 +508,11 @@
 
         // This is redundant to index stuff
         if (type.equals("documents") || type.equals("base/texts")) {
-            if (this.cb == null)
+            if (this.cbi == null) {
+                if (this.index.reader() == null)
+                    return (long) 0;
                 return (long) this.index.reader().numDocs();
+            }
             else
                 return this.docCount();
         };
@@ -516,11 +521,18 @@
         // This may be prefixed by foundries
         Term term = new Term(field, "-:" + type);
 
+        if (DEBUG)
+            log.debug("Iterate for {}/{}", field, type);
+
         long occurrences = 0;
         try {
             // Iterate over all atomic readers and collect occurrences
             for (AtomicReaderContext atomic : this.index.reader().leaves()) {
-                occurrences += this._numberOfAtomic(this.bits(atomic), atomic, term);
+                Bits bits = this.bits(atomic);
+                if (bits != null)
+                    occurrences += this._numberOfAtomic(bits, atomic, term);
+                if (DEBUG)
+                    log.debug("Added up to {} for {}/{} with {}", occurrences, field, type, bits);
             };
         }
         
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 5bd91a7..1cb804c 100644
--- a/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java
+++ b/src/main/java/de/ids_mannheim/korap/collection/CollectionBuilder.java
@@ -155,6 +155,9 @@
         };
 
         public CollectionBuilderGroup with (CollectionBuilderInterface cb) {
+            if (cb == null)
+                return this;
+
             if (!cb.isNegative())
                 this.isNegative = false;
             this.operands.add(cb);
diff --git a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
index a41bc59..398c7b0 100644
--- a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionIndex.java
@@ -6,10 +6,21 @@
 import de.ids_mannheim.korap.collection.CollectionBuilder;
 import de.ids_mannheim.korap.index.FieldDocument;
 import de.ids_mannheim.korap.index.TextAnalyzer;
+import de.ids_mannheim.korap.response.Result;
+import de.ids_mannheim.korap.KrillQuery;
+import de.ids_mannheim.korap.query.QueryBuilder;
+
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.spans.SpanOrQuery;
+import org.apache.lucene.search.spans.SpanQuery;
+import org.apache.lucene.search.spans.SpanTermQuery;
+import org.apache.lucene.search.spans.SpanQuery;
+
+
 
 import static org.junit.Assert.*;
 import org.junit.Test;
@@ -316,6 +327,174 @@
     };
 
 
+    @Test
+    public void filterExampleFromLegacy () throws Exception {
+
+        // Construct index
+        KrillIndex ki = new KrillIndex();
+        // Indexing test files
+        for (String i : new String[] { "00001", "00002", "00003", "00004",
+                "00005", "00006", "02439" }) {
+            ki.addDoc(
+                    getClass().getResourceAsStream("/wiki/" + i + ".json.gz"),
+                    true);
+        };
+        ki.commit();
+
+        // Create Virtual collections:
+        KrillCollection kc = new KrillCollection(ki);
+
+        assertEquals("Documents", 7, kc.numberOf("documents"));
+
+        // The virtual collection consists of all documents that have
+        // the textClass "reisen" and "freizeit"
+
+        /*        kc.filter(kf.and("textClass", "reisen").and("textClass",
+                "freizeit-unterhaltung"));
+        */
+
+        kc.fromBuilder(kc.build().andGroup().with(kc.build().term("textClass", "reisen")).with(kc.build().term("textClass", "freizeit-unterhaltung")));
+
+        assertEquals("Documents", 5, kc.numberOf("documents"));
+        assertEquals("Tokens", 1678, kc.numberOf("tokens"));
+        assertEquals("Sentences", 194, kc.numberOf("sentences"));
+        assertEquals("Paragraphs", 139, kc.numberOf("paragraphs"));
+
+
+        // Subset this to all documents that have also the text
+        // kc.filter(kf.and("textClass", "kultur"));
+        /*
+        kc.fromBuilder(
+          kc.build().andGroup().with(
+            kc.getBuilder()
+          ).with(
+            kc.build().term("textClass", "kultur")
+          )
+        );
+        */
+
+        kc.filter(kc.build().term("textClass", "kultur"));
+
+        assertEquals("Documents", 1, kc.numberOf("documents"));
+        assertEquals("Tokens", 405, kc.numberOf("tokens"));
+        assertEquals("Sentences", 75, kc.numberOf("sentences"));
+        assertEquals("Paragraphs", 48, kc.numberOf("paragraphs"));
+
+
+        // kc.filter(kf.and("corpusID", "WPD"));
+        kc.filter(kc.build().term("corpusID", "WPD"));
+
+        assertEquals("Documents", 1, kc.numberOf("documents"));
+        assertEquals("Tokens", 405, kc.numberOf("tokens"));
+        assertEquals("Sentences", 75, kc.numberOf("sentences"));
+        assertEquals("Paragraphs", 48, kc.numberOf("paragraphs"));
+
+        // Create a query
+        QueryBuilder kq = new QueryBuilder("tokens");
+        SpanQuery query = kq.seg("opennlp/p:NN").with("tt/p:NN").toQuery();
+
+        Result kr = ki.search(kc, query, 0, (short) 20, true, (short) 5, true, (short) 5);
+        assertEquals(kr.getTotalResults(), 70);
+
+
+        kc.extend(kc.build().term("textClass", "uninteresting"));
+        assertEquals("Documents", 1, kc.numberOf("documents"));
+
+        kc.extend(kc.build().term("textClass", "wissenschaft"));
+
+        assertEquals("Documents", 3, kc.numberOf("documents"));
+        assertEquals("Tokens", 1669, kc.numberOf("tokens"));
+        assertEquals("Sentences", 188, kc.numberOf("sentences"));
+        assertEquals("Paragraphs", 130, kc.numberOf("paragraphs"));
+        // System.err.println(kr.toJSON());
+    };
+
+
+    @Test
+    public void filterExampleAtomicLegacy () throws Exception {
+
+        // That's exactly the same test class, but with multiple atomic indices
+
+        // Construct index
+        KrillIndex ki = new KrillIndex();
+        // Indexing test files
+        for (String i : new String[] { "00001", "00002", "00003", "00004",
+                "00005", "00006", "02439" }) {
+            ki.addDoc(
+                    getClass().getResourceAsStream("/wiki/" + i + ".json.gz"),
+                    true);
+            ki.commit();
+        };
+
+        CollectionBuilder kf = new CollectionBuilder();
+
+        // Create Virtual collections:
+        KrillCollection kc = new KrillCollection(ki);
+
+        assertEquals("Documents", 7, kc.numberOf("documents"));
+
+        // If this is set - everything is fine automatically ...
+        kc.filter(kc.build().term("corpusID", "WPD"));
+
+        assertEquals("Documents", 7, kc.numberOf("documents"));
+
+        // The virtual collection consists of all documents that have the textClass "reisen" and "freizeit"
+
+        /*
+        kc.filter(kf.and("textClass", "reisen").and("textClass",
+                "freizeit-unterhaltung"));
+        */
+        kc.filter(kc.build().andGroup().with(kc.build().term("textClass", "reisen")).with(kc.build().term("textClass", "freizeit-unterhaltung")));
+
+        assertEquals("Documents", 5, kc.numberOf("documents"));
+        assertEquals("Tokens", 1678, kc.numberOf("tokens"));
+        assertEquals("Sentences", 194, kc.numberOf("sentences"));
+        assertEquals("Paragraphs", 139, kc.numberOf("paragraphs"));
+
+        // Subset this to all documents that have also the text
+        // kc.filter(kf.and("textClass", "kultur"));
+
+        kc.filter(kc.build().term("textClass", "kultur"));
+
+        assertEquals("Documents", 1, kc.numberOf("documents"));
+        assertEquals("Tokens", 405, kc.numberOf("tokens"));
+        assertEquals("Sentences", 75, kc.numberOf("sentences"));
+        assertEquals("Paragraphs", 48, kc.numberOf("paragraphs"));
+
+        // This is already filtered though ...
+        // kc.filter(kf.and("corpusID", "WPD"));
+        kc.filter(kc.build().term("corpusID", "WPD"));
+
+        assertEquals("Documents", 1, kc.numberOf("documents"));
+        assertEquals("Tokens", 405, kc.numberOf("tokens"));
+        assertEquals("Sentences", 75, kc.numberOf("sentences"));
+        assertEquals("Paragraphs", 48, kc.numberOf("paragraphs"));
+
+        // Create a query
+        QueryBuilder kq = new QueryBuilder("tokens");
+        SpanQuery query = kq.seg("opennlp/p:NN").with("tt/p:NN").toQuery();
+
+        Result kr = ki.search(kc, query, 0, (short) 20, true, (short) 5, true, (short) 5);
+        assertEquals(kr.getTotalResults(), 70);
+
+        // kc.extend(kf.and("textClass", "uninteresting"));
+        kc.extend(kc.build().term("textClass", "uninteresting"));
+
+        /*
+
+
+        assertEquals("Documents", 1, kc.numberOf("documents"));
+
+        kc.extend(kf.and("textClass", "wissenschaft"));
+
+        assertEquals("Documents", 3, kc.numberOf("documents"));
+        assertEquals("Tokens", 1669, kc.numberOf("tokens"));
+        assertEquals("Sentences", 188, kc.numberOf("sentences"));
+        assertEquals("Paragraphs", 130, kc.numberOf("paragraphs"));
+        */
+    };
+
+
     private FieldDocument createDoc1 () {
         FieldDocument fd = new FieldDocument();
         fd.addString("ID", "doc-1");
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 287ceba..8b067b5 100644
--- a/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionLegacy.java
+++ b/src/test/java/de/ids_mannheim/korap/collection/TestKrillCollectionLegacy.java
@@ -14,10 +14,10 @@
 import org.apache.lucene.search.spans.SpanOrQuery;
 import org.apache.lucene.search.spans.SpanQuery;
 import org.apache.lucene.search.spans.SpanTermQuery;
-import org.apache.lucene.search.spans.SpanQuery;
 
 import static org.junit.Assert.*;
 import org.junit.Test;
+import org.junit.Ignore;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
@@ -25,6 +25,7 @@
 public class TestKrillCollectionLegacy {
 
     @Test
+    @Ignore
     public void filterExample () throws Exception {
 
         // Construct index
@@ -92,6 +93,7 @@
 
 
     @Test
+    @Ignore
     public void filterExampleAtomic () throws Exception {
 
         // That's exactly the same test class, but with multiple atomic indices
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestMatchIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestMatchIndex.java
index 82724b0..464f4e1 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestMatchIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestMatchIndex.java
@@ -480,7 +480,7 @@
 
         fail("Skipping may go horribly wrong! (Known issue)");
 
-        kr = kc.search(sq);
+        kr = ki.search(kc, sq, 0, (short) 20, true, (short) 5, true, (short) 5);
         //        System.err.println(kr.getOverview());
 
 
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 2f23d35..01d1a4b 100644
--- a/src/test/java/de/ids_mannheim/korap/search/TestKrill.java
+++ b/src/test/java/de/ids_mannheim/korap/search/TestKrill.java
@@ -944,6 +944,7 @@
         sc.right.setLength((short) 10);
 
         Result kr = ks.apply(ki);
+
         assertEquals(kr.getMatch(1).getSnippetBrackets(),
                 "... dezimalen [Wert] 65 sowohl ...");
         assertEquals(kr.getTotalResults(), 3);
diff --git a/src/test/resources/queries/bsp-context-2.jsonld b/src/test/resources/queries/bsp-context-2.jsonld
index 481ab44..ddefd0e 100644
--- a/src/test/resources/queries/bsp-context-2.jsonld
+++ b/src/test/resources/queries/bsp-context-2.jsonld
@@ -1,29 +1,36 @@
 {
-    "@context": "http://ids-mannheim.de/ns/KorAP/json-ld/v0.1/context.jsonld",
-    "query":{
-	"@type":"koral:token",
-	"wrap":{
-	    "@type":"koral:term",
-	    "foundry" : "mate",
-	    "layer":"l",
-	    "key":"wert",
-	    "match":"match:eq"
-	}
-    },
-    "collections":[
-	{
-	    "@type":"koral:meta-filter",
-	    "@value":{
-		"@type":"koral:term",
-		"@field":"koral:field#corpusID",
-		"@value":"WPD"
-	    }
-	}
-    ],
-    "meta":{
-	"startPage":1,
-	"count":25,
-	"context":{"left":["char",210],"right":["char",210]},
-	"cutOff":true
+  "@context": "http://ids-mannheim.de/ns/KorAP/json-ld/v0.1/context.jsonld",
+  "query":{
+    "@type":"koral:token",
+    "wrap":{
+      "@type":"koral:term",
+      "foundry" : "mate",
+      "layer":"l",
+      "key":"wert",
+      "match":"match:eq"
     }
+  },
+  "collection" : {
+    "@type": "koral:doc",
+    "key": "corpusID",
+    "match": "match:eq",
+    "value": "WPD",
+    "type": "type:string"
+  },
+  "collections":[
+    {
+      "@type":"koral:meta-filter",
+      "@value":{
+	"@type":"koral:term",
+	"@field":"koral:field#corpusID",
+	"@value":"WPD"
+      }
+    }
+  ],
+  "meta":{
+    "startPage":1,
+    "count":25,
+    "context":{"left":["char",210],"right":["char",210]},
+    "cutOff":true
+  }
 }
diff --git a/src/test/resources/queries/bsp-context-sentence.jsonld b/src/test/resources/queries/bsp-context-sentence.jsonld
index 28488b3..3ba2e94 100644
--- a/src/test/resources/queries/bsp-context-sentence.jsonld
+++ b/src/test/resources/queries/bsp-context-sentence.jsonld
@@ -10,6 +10,13 @@
 	    "match":"match:eq"
 	}
     },
+  "collection" : {
+    "@type": "koral:doc",
+    "key": "corpusID",
+    "match": "match:eq",
+    "value": "WPD",
+    "type": "type:string"
+  },     
     "collections":[
 	{
 	    "@type":"koral:meta-filter",
diff --git a/src/test/resources/queries/bugs/multiterm_rewrite.jsonld b/src/test/resources/queries/bugs/multiterm_rewrite.jsonld
index 3ea96ea..e42d555 100644
--- a/src/test/resources/queries/bugs/multiterm_rewrite.jsonld
+++ b/src/test/resources/queries/bugs/multiterm_rewrite.jsonld
@@ -50,6 +50,13 @@
       }
     ]
   },
+  "collection" : {
+    "@type": "koral:doc",
+    "key": "corpusID",
+    "match": "match:eq",
+    "value": "WPD",
+    "type": "type:string"
+  },     
   "collections":[
     {
       "@type":"koral:meta-filter",
diff --git a/src/test/resources/queries/metaquery4.jsonld b/src/test/resources/queries/metaquery4.jsonld
index 0b6c263..3673d69 100644
--- a/src/test/resources/queries/metaquery4.jsonld
+++ b/src/test/resources/queries/metaquery4.jsonld
@@ -18,6 +18,26 @@
       "match":"match:eq"
     }
   },
+  "collection" : {
+    "@type": "koral:docGroup",
+    "operation": "operation:and",
+    "operands": [
+      {
+	"@type": "koral:doc",
+	"key": "pubDate",
+	"match": "match:geq",
+	"value": "2000-01-01",
+	"type": "type:date"
+      },
+      {
+	"@type": "koral:doc",
+	"key": "pubDate",
+	"match": "match:leq",
+	"value": "2013-12-31",
+	"type": "type:date"
+      }
+    ]
+  },
   "collections": [
     {
       "@type": "koral:meta-filter",
diff --git a/src/test/resources/queries/metaquery5.jsonld b/src/test/resources/queries/metaquery5.jsonld
index 06141c3..2d2ccd4 100644
--- a/src/test/resources/queries/metaquery5.jsonld
+++ b/src/test/resources/queries/metaquery5.jsonld
@@ -18,6 +18,32 @@
       "match":"match:eq"
     }
   },
+  "collection" : {
+    "@type": "koral:docGroup",
+    "operation": "operation:and",
+    "operands": [
+      {
+	"@type": "koral:docGroup",
+	"operation": "operation:and",
+	"operands": [
+	  {
+	    "@type": "koral:doc",
+	    "key": "pubDate",
+	    "match": "match:geq",
+	    "value": "2000-01-01",
+	    "type": "type:date"
+	  },
+	  {
+	    "@type": "koral:doc",
+	    "key": "pubDate",
+	    "match": "match:leq",
+	    "value": "2013-12-31",
+	    "type": "type:date"
+	  }
+	]
+      }
+    ]
+  },
   "collections": [
     {
       "@type": "koral:meta-filter",
diff --git a/src/test/resources/queries/metaquery6.jsonld b/src/test/resources/queries/metaquery6.jsonld
index 2d4b8e1..4abcd6f 100644
--- a/src/test/resources/queries/metaquery6.jsonld
+++ b/src/test/resources/queries/metaquery6.jsonld
@@ -17,6 +17,32 @@
       "key":"lediglich"
     }
   },
+  "collection" : {
+    "@type": "koral:docGroup",
+    "operation": "operation:and",
+    "operands": [
+      {
+	"@type": "koral:docGroup",
+	"operation": "operation:and",
+	"operands": [
+	  {
+	    "@type": "koral:doc",
+	    "key": "pubDate",
+	    "match": "match:geq",
+	    "value": "2005-01-01",
+	    "type": "type:date"
+	  },
+	  {
+	    "@type": "koral:doc",
+	    "key": "pubDate",
+	    "match": "match:leq",
+	    "value": "2013-12-31",
+	    "type": "type:date"
+	  }
+	]
+      }
+    ]
+  },
   "collections": [
     {
       "@type": "koral:meta-filter",
diff --git a/src/test/resources/queries/metas/fields.jsonld b/src/test/resources/queries/metas/fields.jsonld
index 845f3f8..7bac417 100644
--- a/src/test/resources/queries/metas/fields.jsonld
+++ b/src/test/resources/queries/metas/fields.jsonld
@@ -1,6 +1,13 @@
 {
   "@context" : "http://ids-mannheim.de/ns/KorAP/json-ld/v0.2/context.jsonld",
   "announcements" : [],
+  "collection" : {
+    "@type": "koral:doc",
+    "key": "corpusID",
+    "match": "match:eq",
+    "value": "WPD",
+    "type": "type:string"
+  },     
   "collections" : [
     {
       "@type" : "koral:meta-filter",
diff --git a/src/test/resources/queries/metas/fields_2.jsonld b/src/test/resources/queries/metas/fields_2.jsonld
index 02c2474..fa10af4 100644
--- a/src/test/resources/queries/metas/fields_2.jsonld
+++ b/src/test/resources/queries/metas/fields_2.jsonld
@@ -1,6 +1,14 @@
 {
   "@context" : "http://ids-mannheim.de/ns/KorAP/json-ld/v0.2/context.jsonld",
   "announcements" : [],
+  "collection" : {
+    "@type": "koral:doc",
+    "key": "corpusID",
+    "match": "match:eq",
+    "value": "WPD",
+    "type": "type:string"
+  },     
+
   "collections" : [
     {
       "@type" : "koral:meta-filter",