diff --git a/src/main/java/de/thm/arsnova/persistance/couchdb/InitializingCouchDbConnector.java b/src/main/java/de/thm/arsnova/persistance/couchdb/InitializingCouchDbConnector.java
index 126504089a0f6252e5b0c24b22bb4c24734a718b..a5785a7e9c3877587047b71e5a9489b06c621ee4 100644
--- a/src/main/java/de/thm/arsnova/persistance/couchdb/InitializingCouchDbConnector.java
+++ b/src/main/java/de/thm/arsnova/persistance/couchdb/InitializingCouchDbConnector.java
@@ -1,10 +1,11 @@
 package de.thm.arsnova.persistance.couchdb;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
+import de.thm.arsnova.entities.Content;
+import de.thm.arsnova.persistance.couchdb.support.MangoCouchDbConnector;
 import org.ektorp.CouchDbInstance;
 import org.ektorp.DocumentNotFoundException;
 import org.ektorp.impl.ObjectMapperFactory;
-import org.ektorp.impl.StdCouchDbConnector;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.InitializingBean;
@@ -24,7 +25,7 @@ import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.List;
 
-public class InitializingCouchDbConnector extends StdCouchDbConnector implements InitializingBean, ResourceLoaderAware {
+public class InitializingCouchDbConnector extends MangoCouchDbConnector implements InitializingBean, ResourceLoaderAware {
 	private static final Logger logger = LoggerFactory.getLogger(InitializingCouchDbConnector.class);
 	private final List<Bindings> docs = new ArrayList<>();
 
diff --git a/src/main/java/de/thm/arsnova/persistance/couchdb/support/MangoCouchDbConnector.java b/src/main/java/de/thm/arsnova/persistance/couchdb/support/MangoCouchDbConnector.java
new file mode 100644
index 0000000000000000000000000000000000000000..4f4eb6197ecf57796712020bd4625e9c8be356f5
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/persistance/couchdb/support/MangoCouchDbConnector.java
@@ -0,0 +1,217 @@
+package de.thm.arsnova.persistance.couchdb.support;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonView;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+import com.fasterxml.jackson.databind.util.Converter;
+import de.thm.arsnova.entities.serialization.View;
+import org.ektorp.CouchDbInstance;
+import org.ektorp.DbAccessException;
+import org.ektorp.impl.ObjectMapperFactory;
+import org.ektorp.impl.StdCouchDbConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This Connector adds a query method which uses CouchDB's Mango API to retrieve data.
+ */
+public class MangoCouchDbConnector extends StdCouchDbConnector {
+	@JsonInclude(JsonInclude.Include.NON_DEFAULT)
+	/**
+	 * Represents a <code>_find</code> query for CouchDB's Mango API.
+	 * See http://docs.couchdb.org/en/stable/api/database/find.html#db-find.
+	 */
+	public class MangoQuery {
+		@JsonSerialize(converter = Sort.ToListConverter.class)
+		public class Sort {
+			public class ToListConverter implements Converter<Sort, List<String>> {
+				@Override
+				public List<String> convert(Sort value) {
+					return Arrays.asList(value.field, value.descending ? "desc" : "asc");
+				}
+
+				@Override
+				public JavaType getInputType(TypeFactory typeFactory) {
+					return typeFactory.constructType(Sort.class);
+				}
+
+				@Override
+				public JavaType getOutputType(TypeFactory typeFactory) {
+					return typeFactory.constructGeneralizedType(typeFactory.constructType(List.class), String.class);
+				}
+			}
+
+			private String field;
+			private boolean descending = false;
+
+			public Sort(String field, boolean descending) {
+				this.field = field;
+				this.descending = descending;
+			}
+
+			public String getField() {
+				return field;
+			}
+
+			public void setField(String field) {
+				this.field = field;
+			}
+
+			public boolean isDescending() {
+				return descending;
+			}
+
+			public void setDescending(boolean descending) {
+				this.descending = descending;
+			}
+		}
+
+		private Map<String, Object> selector;
+		private List<String> fields = new ArrayList<>();
+		private List<Sort> sort = new ArrayList<>();
+		private int limit = 0;
+		private int skip = 0;
+		private String indexDocument;
+		private String indexName;
+		private boolean update = true;
+		private boolean stable = false;
+
+		public MangoQuery() {
+			this.selector = new HashMap<>();
+		}
+
+		/**
+		 * @param selector See http://docs.couchdb.org/en/stable/api/database/find.html#selector-syntax.
+		 */
+		public MangoQuery(Map<String, Object> selector) {
+			this.selector = selector;
+		}
+
+		@JsonView(View.Persistence.class)
+		public Map<String, ?> getSelector() {
+			return selector;
+		}
+
+		/**
+		 * @param selector See http://docs.couchdb.org/en/stable/api/database/find.html#selector-syntax.
+		 */
+		public void setSelector(Map<String, Object> selector) {
+			this.selector = selector;
+		}
+
+		@JsonView(View.Persistence.class)
+		public List<String> getFields() {
+			return fields;
+		}
+
+		public void setFields(List<String> fields) {
+			this.fields = fields;
+		}
+
+		@JsonView(View.Persistence.class)
+		public List<Sort> getSort() {
+			return sort;
+		}
+
+		public void setSort(List<Sort> sort) {
+			this.sort = sort;
+		}
+
+		@JsonView(View.Persistence.class)
+		public int getLimit() {
+			return limit;
+		}
+
+		public void setLimit(int limit) {
+			this.limit = limit;
+		}
+
+		@JsonView(View.Persistence.class)
+		public int getSkip() {
+			return skip;
+		}
+
+		public void setSkip(int skip) {
+			this.skip = skip;
+		}
+
+		public String getIndexDocument() {
+			return indexDocument;
+		}
+
+		public void setIndexDocument(String indexDocument) {
+			this.indexDocument = indexDocument;
+		}
+
+		public String getIndexName() {
+			return indexName;
+		}
+
+		public void setIndexName(String indexName) {
+			this.indexName = indexName;
+		}
+
+		@JsonView(View.Persistence.class)
+		public Object getIndex() {
+			return indexName != null ? new String[] {indexDocument, indexName} : indexDocument;
+		}
+
+		@JsonView(View.Persistence.class)
+		public boolean isUpdate() {
+			return update;
+		}
+
+		public void setUpdate(boolean update) {
+			this.update = update;
+		}
+
+		@JsonView(View.Persistence.class)
+		public boolean isStable() {
+			return stable;
+		}
+
+		public void setStable(boolean stable) {
+			this.stable = stable;
+		}
+	}
+
+	private static final Logger logger = LoggerFactory.getLogger(MangoCouchDbConnector.class);
+
+	public MangoCouchDbConnector(String databaseName, CouchDbInstance dbInstance) {
+		super(databaseName, dbInstance);
+	}
+
+	public MangoCouchDbConnector(String databaseName, CouchDbInstance dbi, ObjectMapperFactory om) {
+		super(databaseName, dbi, om);
+	}
+
+	/**
+	 *
+	 * @param query The query sent to CouchDB's Mango API
+	 * @param type Type for deserialization of retrieved entities
+	 * @return List of retrieved entities
+	 */
+	public <T> List<T> query(final MangoQuery query, final Class<T> type) {
+		MangoResponseHandler<T> rh = new MangoResponseHandler<T>(type, objectMapper, true);
+		String queryString;
+		try {
+			queryString = objectMapper.writeValueAsString(query);
+			logger.debug("Querying CouchDB using Mango API: {}", queryString);
+		} catch (JsonProcessingException e) {
+			throw new DbAccessException("Could not serialize Mango query.");
+		}
+		List<T> result = restTemplate.post(dbURI.append("_find").toString(), queryString, rh);
+		logger.debug("Answer from CouchDB Mango query: {}", result);
+
+		return result;
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/persistance/couchdb/support/MangoQueryResultParser.java b/src/main/java/de/thm/arsnova/persistance/couchdb/support/MangoQueryResultParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..7367787f539098ce75769c789eb988152976bf06
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/persistance/couchdb/support/MangoQueryResultParser.java
@@ -0,0 +1,89 @@
+package de.thm.arsnova.persistance.couchdb.support;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.ektorp.DbAccessException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MangoQueryResultParser<T> {
+	private static final String DOCS_FIELD_NAME = "docs";
+	private static final String WARNING_FIELD_NAME = "warning";
+	private static final String ERROR_FIELD_NAME = "error";
+	private static final String REASON_FIELD_NAME = "reason";
+
+	private static final Logger logger = LoggerFactory.getLogger(MangoQueryResultParser.class);
+
+	private Class<T> type;
+	private ObjectMapper objectMapper;
+	private List<T> docs;
+
+	public MangoQueryResultParser(Class<T> type, ObjectMapper objectMapper) {
+		this.type = type;
+		this.objectMapper = objectMapper;
+	}
+
+	public void parseResult(InputStream json) throws IOException {
+		JsonParser jp = objectMapper.getFactory().createParser(json);
+
+		try {
+			parseResult(jp);
+		} finally {
+			jp.close();
+		}
+	}
+
+	private void parseResult(JsonParser jp) throws IOException {
+		if (jp.nextToken() != JsonToken.START_OBJECT) {
+			throw new DbAccessException("Expected data to start with an Object");
+		}
+
+		String error = null;
+		String reason = null;
+
+		// Issue #98: Can't assume order of JSON fields.
+		while (jp.nextValue() != JsonToken.END_OBJECT) {
+			String currentName = jp.getCurrentName();
+			if (DOCS_FIELD_NAME.equals(currentName)) {
+				docs = new ArrayList<T>();
+				parseDocs(jp);
+			} else if (WARNING_FIELD_NAME.equals(currentName)) {
+				logger.warn("Warning for CouchDB Mango query: {}", jp.getText());
+			} else if (ERROR_FIELD_NAME.equals(currentName)) {
+				error = jp.getText();
+			} else if (REASON_FIELD_NAME.equals(currentName)) {
+				reason = jp.getText();
+			}
+		}
+
+		if (error != null) {
+			String errorDesc = reason != null ? reason : error;
+			throw new DbAccessException("CouchDB Mango query failed: " + errorDesc);
+		}
+	}
+
+	private void parseDocs(JsonParser jp) throws IOException {
+		if (jp.getCurrentToken() != JsonToken.START_ARRAY) {
+			throw new DbAccessException("Expected rows to start with an Array");
+		}
+
+		while (jp.nextToken() == JsonToken.START_OBJECT) {
+			T doc = jp.readValueAs(type);
+			docs.add(doc);
+		}
+
+		if (jp.currentToken() != JsonToken.END_ARRAY) {
+			throw new DbAccessException("Cannot parse response from CouchDB. Unexpected data.");
+		}
+	}
+
+	public List<T> getDocs() {
+		return docs;
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/persistance/couchdb/support/MangoResponseHandler.java b/src/main/java/de/thm/arsnova/persistance/couchdb/support/MangoResponseHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..462555e7abd12682836bfcc1d223a5b68ab9970e
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/persistance/couchdb/support/MangoResponseHandler.java
@@ -0,0 +1,32 @@
+package de.thm.arsnova.persistance.couchdb.support;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.ektorp.http.HttpResponse;
+import org.ektorp.http.StdResponseHandler;
+import org.ektorp.util.Assert;
+
+import java.util.List;
+
+public class MangoResponseHandler<T> extends StdResponseHandler<List<T>> {
+
+	private MangoQueryResultParser<T> parser;
+
+	public MangoResponseHandler(Class<T> docType, ObjectMapper om) {
+		Assert.notNull(om, "ObjectMapper may not be null");
+		Assert.notNull(docType, "docType may not be null");
+		parser = new MangoQueryResultParser<T>(docType, om);
+	}
+
+	public MangoResponseHandler(Class<T> docType, ObjectMapper om,
+										  boolean ignoreNotFound) {
+		Assert.notNull(om, "ObjectMapper may not be null");
+		Assert.notNull(docType, "docType may not be null");
+		parser = new MangoQueryResultParser<T>(docType, om);
+	}
+
+	@Override
+	public List<T> success(HttpResponse hr) throws Exception {
+		parser.parseResult(hr.getContent());
+		return parser.getDocs();
+	}
+}