diff --git a/config/vufind/config.ini b/config/vufind/config.ini
index 804128bdbaeb1c22c05e702f11d43a75521466de..0d581833e646b0a9164658919cee63ddb2fcc2f7 100644
--- a/config/vufind/config.ini
+++ b/config/vufind/config.ini
@@ -742,11 +742,19 @@ url             = https://www.myendnoteweb.com/EndNoteWeb.html
 ;
 ; If set_field is set, the named Solr field will be used to generate sets on
 ; your OAI-PMH server.  If it is not set, sets will not be supported.
+;
+; If set_query is set (as an array mapping set names to Solr queries -- see
+; examples below), the specified queries will be exposed as OAI sets.  If
+; you use both set_field and set_query, be careful about the names you choose
+; for your set queries. set_query names will trump set_field values when
+; there are collisions.
 ;[OAI]
 ;identifier       = myuniversity.edu
 ;repository_name  = "MyUniversity Catalog"
 ;admin_email      = oai@myuniversity.edu
 ;set_field        = "format"
+;set_query['eod_books'] = "institution:kfu AND publishDate:[1911 TO 1911]"
+;set_query['eod_ebooks'] = "format:eBook"
 
 ; Proxy Server is Optional.
 [Proxy]
diff --git a/module/VuFind/src/VuFind/OAI/Server.php b/module/VuFind/src/VuFind/OAI/Server.php
index 2866d4629e9265192eb018cc59cc953815d76398..4702c8e45116c0c66332b6651bc81e4fa81ee1aa 100644
--- a/module/VuFind/src/VuFind/OAI/Server.php
+++ b/module/VuFind/src/VuFind/OAI/Server.php
@@ -161,6 +161,13 @@ class Server
      */
     protected $recordLinkHelper = null;
 
+    /**
+     * Set queries
+     *
+     * @var array
+     */
+    protected $setQueries = array();
+
     /**
      * Constructor
      *
@@ -471,6 +478,11 @@ class Server
         if (isset($config->OAI->set_field)) {
             $this->setField = $config->OAI->set_field;
         }
+
+        // Initialize custom sets queries:
+        if (isset($config->OAI->set_query)) {
+            $this->setQueries = $config->OAI->set_query->toArray();
+        }
     }
 
     /**
@@ -618,30 +630,44 @@ class Server
         }
 
         // If no set field is enabled, we can't provide a set list:
-        if (is_null($this->setField)) {
+        if (null === $this->setField && empty($this->setQueries)) {
             return $this->showError('noSetHierarchy', 'Sets not supported');
         }
 
-        // If we got this far, we can load all available set values.  For now,
-        // we'll assume that this list is short enough to load in a single response;
-        // it may be necessary to implement a resumption token mechanism if this
-        // proves not to be the case:
-        $results = $this->resultsManager->get($this->searchClassId);
-        try {
-            $facets = $results->getFullFieldFacets(array($this->setField));
-        } catch (\Exception $e) {
-            $facets = null;
-        }
-        if (empty($facets) || !isset($facets[$this->setField]['data']['list'])) {
-            $this->unexpectedError('Cannot find sets');
+        // Begin building XML:
+        $xml = new SimpleXMLElement('<ListSets />');
+
+        // Load set field if applicable:
+        if (null !== $this->setField) {
+            // If we got this far, we can load all available set values.  For now,
+            // we'll assume that this list is short enough to load in one response;
+            // it may be necessary to implement a resumption token mechanism if this
+            // proves not to be the case:
+            $results = $this->resultsManager->get($this->searchClassId);
+            try {
+                $facets = $results->getFullFieldFacets(array($this->setField));
+            } catch (\Exception $e) {
+                $facets = null;
+            }
+            if (empty($facets) || !isset($facets[$this->setField]['data']['list'])) {
+                $this->unexpectedError('Cannot find sets');
+            }
+    
+            // Extract facet values from the Solr response:
+            foreach ($facets[$this->setField]['data']['list'] as $x) {
+                $set = $xml->addChild('set');
+                $set->setSpec = $x['value'];
+                $set->setName = $x['displayText'];
+            }
         }
 
-        // Extract facet values from the Solr response:
-        $xml = new SimpleXMLElement('<ListSets />');
-        foreach ($facets[$this->setField]['data']['list'] as $x) {
-            $set = $xml->addChild('set');
-            $set->setSpec = $x['value'];
-            $set->setName = $x['displayText'];
+        // Iterate over custom sets:
+        if (!empty($this->setQueries)) {
+            foreach ($this->setQueries as $setName => $solrQuery) {
+                $set = $xml->addChild('set');
+                $set->setSpec = $solrQuery;
+                $set->setName = $setName;
+            }
         }
 
         // Display the list:
@@ -694,10 +720,14 @@ class Server
         );
 
         // Apply filters as needed.
-        if (!empty($set) && !is_null($this->setField)) {
-            $params->addFilter(
-                $this->setField . ':"' . addcslashes($set, '"') . '"'
-            );
+        if (!empty($set)) {
+            if (isset($this->setQueries[$set])) {
+                $params->addFilter($this->setQueries[$set]);
+            } else if (null !== $this->setField) {
+                $params->addFilter(
+                    $this->setField . ':"' . addcslashes($set, '"') . '"'
+                );
+            }
         }
 
         // Perform a Solr search: