containment of word in metadata field
diff --git a/src/main/antlr/CollectionQuery.g4 b/src/main/antlr/CollectionQuery.g4
index bf9422f..5949b73 100644
--- a/src/main/antlr/CollectionQuery.g4
+++ b/src/main/antlr/CollectionQuery.g4
@@ -83,7 +83,7 @@
 ;
 
 operator
-:	(NEG? EQ) | LT | GT | LEQ | GEQ;
+:	(NEG? EQ) | LT | GT | LEQ | GEQ | TILDE;
 
 expr
 : meta
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryTree.java
index dc3405a..8cecce4 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryTree.java
@@ -101,7 +101,7 @@
                 String match = operatorNodes.get(0).getText();
                 term.put("match", "match:" + interpretMatch(match));
                 if (checkOperatorValueConformance(term) == 1) {
-                	requestMap.put("query", new LinkedHashMap<String,Object>());
+                	requestMap.put("collection", new LinkedHashMap<String,Object>());
                 	return;
                 }
                 putIntoSuperObject(term);
@@ -116,7 +116,7 @@
                 term1.put("match", "match:" + invertInequation(interpretMatch(match1)));
                 termGroupOperands.add(term1);
                 if (checkOperatorValueConformance(term1) == 1) {
-                	requestMap.put("query", new LinkedHashMap<String,Object>());
+                	requestMap.put("collection", new LinkedHashMap<String,Object>());
                 	return;
                 }
 
@@ -127,7 +127,7 @@
                 term2.put("match", "match:" + interpretMatch(match2));
                 termGroupOperands.add(term2);
                 if (checkOperatorValueConformance(term2) == 1) {
-                	requestMap.put("query", new LinkedHashMap<String,Object>());
+                	requestMap.put("collection", new LinkedHashMap<String,Object>());
                 	return;
                 }
 
@@ -216,7 +216,7 @@
 		String match = (String) term.get("match");
 		String type = (String) term.get("type");
 		if (type == null || type.equals("type:regex")) {
-			if (!(match.equals("match:eq") || match.equals("match:ne"))) {
+			if (!(match.equals("match:eq") || match.equals("match:ne") || match.equals("match:contains"))) {
 				errorMsgs.add("You used an inequation operator with a string value.");
 				System.err.println("You used an inequation operator with a string value.");
 				return 1;
@@ -262,6 +262,10 @@
             case "!=":
                 out = "ne";
                 break;
+            case "~":
+                out = "contains";
+                break;    
+               
         }
         return out;
     }
@@ -297,7 +301,7 @@
         } else {
             // I want the raw object, not a wrapped
 //            requestMap.put("filter", object);
-        	requestMap.put("query", object);
+        	requestMap.put("collection", object);
         }
     }
 
@@ -433,6 +437,7 @@
         query = "1990<year<2010 & genre=Sport";
         query = "1990<year<2010";
         query = "pubDate<Sport";
+        query = "title~Hamburg";
 //        query = "foo=b-ar";
 //    	filter.verbose = true;
         CollectionQueryTree filter = null;
diff --git a/src/test/java/CollectionQueryTreeTest.java b/src/test/java/CollectionQueryTreeTest.java
index cf7c398..349b98a 100644
--- a/src/test/java/CollectionQueryTreeTest.java
+++ b/src/test/java/CollectionQueryTreeTest.java
@@ -10,14 +10,6 @@
 	private String query;
 	private String expected;
 
-	private boolean equalsQueryContent(String res, String query) throws QueryException {
-		res = res.replaceAll(" ", "");
-		cqt = new CollectionQueryTree();
-		cqt.process(query);
-		String queryMap = cqt.getRequestMap().get("query").toString().replaceAll(" ", "");
-		return res.equals(queryMap);
-	}
-
 	@Test
 	public void testSimple() throws QueryException {
 		query = "textClass=Sport";
@@ -25,7 +17,7 @@
 		expected = "{@type=korap:doc, key=textClass, value=Sport, match=match:eq}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 
 		query = "textClass!=Sport";
@@ -33,7 +25,18 @@
 		expected = "{@type=korap:doc, key=textClass, value=Sport, match=match:ne}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
+		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
+	}
+	
+	@Test
+	public void testContains() throws QueryException {
+		query = "title~Mannheim";
+		expected = 
+			"{@type=korap:doc, key=title, value=Mannheim, match=match:contains}";
+		cqt = new CollectionQueryTree();
+		cqt.process(query);
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 	
@@ -47,7 +50,7 @@
 				"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 	
@@ -64,7 +67,7 @@
 				"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 	
@@ -79,7 +82,7 @@
 				"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 	
@@ -96,7 +99,7 @@
 				"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 
@@ -115,7 +118,7 @@
 				"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query = "(textClass=Sport & textClass=ausland) & corpusID=WPD";
@@ -130,7 +133,7 @@
 				"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query = "(textClass=Sport & textClass=ausland) | (corpusID=WPD & author=White)";
@@ -148,7 +151,7 @@
 				"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query = "(textClass=Sport & textClass=ausland) | (corpusID=WPD & author=White & year=2010)";
@@ -168,7 +171,7 @@
 				"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 
@@ -183,7 +186,7 @@
 				"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query = "pubDate>=1990";
@@ -191,7 +194,7 @@
 				"{@type=korap:doc, key=pubDate, type=type:date, value=1990, match=match:geq}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query = "pubDate>=1990-05";
@@ -199,7 +202,7 @@
 				"{@type=korap:doc, key=pubDate, type=type:date, value=1990-05, match=match:geq}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query = "pubDate>=1990-05-01";
@@ -207,7 +210,7 @@
 				"{@type=korap:doc, key=pubDate, type=type:date, value=1990-05-01, match=match:geq}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 
@@ -218,7 +221,7 @@
 				"{@type=korap:doc, key=author, value=Go.*he, type=type:regex, match=match:eq}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 	
@@ -229,7 +232,7 @@
 				"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=Schwalbe, match=match:eq}}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query = "[cnx/base=Schwalbe]";
@@ -237,7 +240,7 @@
 				"{@type=korap:token, wrap={@type=korap:term, foundry=cnx, layer=lemma, key=Schwalbe, match=match:eq}}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query = "[base!=Schwalbe]";
@@ -245,7 +248,7 @@
 				"{@type=korap:token, wrap={@type=korap:term, layer=lemma, key=Schwalbe, match=match:ne}}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query = "[base=Schwalbe] & [orth=Foul]";
@@ -256,7 +259,7 @@
 					"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}
 	
@@ -270,7 +273,7 @@
 				"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 		
 		query = "[base=Schwalbe] & textClass=Sport";
@@ -281,7 +284,7 @@
 				"]}";
 		cqt = new CollectionQueryTree();
 		cqt.process(query);
-		map = cqt.getRequestMap().toString();
+		map = cqt.getRequestMap().get("collection").toString();
 		assertEquals(expected.replaceAll(" ", ""), map.replaceAll(" ", ""));
 	}