diff --git a/config/vufind/EDS.ini b/config/vufind/EDS.ini
index 9080d6604edc545cbccddfbf0d3cbc3d468eaaab..13d32064dabf383bbf65667637473295e4290003 100644
--- a/config/vufind/EDS.ini
+++ b/config/vufind/EDS.ini
@@ -40,6 +40,13 @@ retain_filters_by_default = true
 ; This is the timeout in seconds when communicating with the EDS server.
 timeout = 120
 
+; This is the HTTP method to use for EDS search operations; legal options are GET
+; or POST (the default). GET and POST use significantly different APIs, so it
+; may be useful to switch between methods for troubleshooting purposes. Under
+; normal circumstances, POST is preferred because GET has some character length
+; limits that do not affect the POST-based API.
+search_http_method = POST
+
 ; The following two sections can be used to associate specific recommendations
 ; modules with specific search types defined in the [Basic_Searches] section
 ; below.  For all the details on how these sections work, see the comments above
diff --git a/module/VuFind/src/VuFind/Search/EDS/Params.php b/module/VuFind/src/VuFind/Search/EDS/Params.php
index bf14d168262058e7c34e86c4e2c569640ed569a4..cb20f35104190320549ea600dfdd7f76ebf15f10 100644
--- a/module/VuFind/src/VuFind/Search/EDS/Params.php
+++ b/module/VuFind/src/VuFind/Search/EDS/Params.php
@@ -27,7 +27,6 @@
  */
 namespace VuFind\Search\EDS;
 
-use VuFindSearch\Backend\EDS\SearchRequestModel as SearchRequestModel;
 use VuFindSearch\ParamBag;
 
 /**
@@ -172,11 +171,8 @@ class Params extends \VuFind\Search\Base\Params
             // Loop through all filters and add appropriate values to request:
             foreach ($filterList as $filterArray) {
                 foreach ($filterArray as $filt) {
-                    $safeValue = SearchRequestModel::escapeSpecialCharacters(
-                        $filt['value']
-                    );
                     // Standard case:
-                    $fq = "{$filt['field']}:{$safeValue}";
+                    $fq = "{$filt['field']}:{$filt['value']}";
                     $params->add('filters', $fq);
                 }
             }
@@ -184,11 +180,8 @@ class Params extends \VuFind\Search\Base\Params
         if (!empty($hiddenFilterList)) {
             foreach ($hiddenFilterList as $field => $hiddenFilters) {
                 foreach ($hiddenFilters as $value) {
-                    $safeValue = SearchRequestModel::escapeSpecialCharacters(
-                        $value
-                    );
                     // Standard case:
-                    $hfq = "{$field}:{$safeValue}";
+                    $hfq = "{$field}:{$value}";
                     $params->add('filters', $hfq);
                 }
             }
diff --git a/module/VuFind/src/VuFind/Search/Factory/EdsBackendFactory.php b/module/VuFind/src/VuFind/Search/Factory/EdsBackendFactory.php
index 927df1696c2331f69f10ff42822d5b1c5262a73b..33508ebac0b5b2e3446013536fdd3c9a5f0ec671 100644
--- a/module/VuFind/src/VuFind/Search/Factory/EdsBackendFactory.php
+++ b/module/VuFind/src/VuFind/Search/Factory/EdsBackendFactory.php
@@ -137,7 +137,9 @@ class EdsBackendFactory implements FactoryInterface
     protected function createConnector()
     {
         $options = [
-            'timeout' => $this->edsConfig->General->timeout ?? 120
+            'timeout' => $this->edsConfig->General->timeout ?? 120,
+            'search_http_method' => $this->edsConfig->General->search_http_method
+                ?? 'POST'
         ];
         // Build HTTP client:
         $client = $this->serviceLocator->get(\VuFindHttp\HttpService::class)
diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/EDS/Base.php b/module/VuFindSearch/src/VuFindSearch/Backend/EDS/Base.php
index facbbafc6103a54213fe19c71a030b4b242a1240..4dd3be3a6fdfdebac2e4c0be29e15f1569fe4067 100644
--- a/module/VuFindSearch/src/VuFindSearch/Backend/EDS/Base.php
+++ b/module/VuFindSearch/src/VuFindSearch/Backend/EDS/Base.php
@@ -81,6 +81,13 @@ abstract class Base
      */
     protected $contentType = 'application/json';
 
+    /**
+     * Search HTTP method
+     *
+     * @var string
+     */
+    protected $searchHttpMethod = 'POST';
+
     /**
      * Constructor
      *
@@ -91,6 +98,7 @@ abstract class Base
      *    <ul>
      *      <li>debug - boolean to control debug mode</li>
      *      <li>orgid - Organization making calls to the EDS API </li>
+     *      <li>search_http_method - HTTP method for search API calls</li>
      *    </ul>
      */
     public function __construct($settings = [])
@@ -104,6 +112,8 @@ abstract class Base
                 case 'orgid':
                     $this->orgId = $value;
                     break;
+                case 'search_http_method':
+                    $this->searchHttpMethod = $value;
                 }
             }
         }
@@ -203,11 +213,15 @@ abstract class Base
     public function search($query, $authenticationToken, $sessionToken)
     {
         // Query String Parameters
-        $qs = $query->convertToQueryStringParameterArray();
-        $this->debugPrint('Query: ' . print_r($qs, true));
+        $method = $this->searchHttpMethod;
+        $json = $method === 'GET' ? null : $query->convertToSearchRequestJSON();
+        $qs = $method === 'GET' ? $query->convertToQueryStringParameterArray() : [];
+        $this->debugPrint(
+            'Query: ' . ($method === 'GET' ? print_r($qs, true) : $json)
+        );
         $url = $this->edsApiHost . '/search';
         $headers = $this->setTokens($authenticationToken, $sessionToken);
-        return $this->call($url, $headers, $qs);
+        return $this->call($url, $headers, $qs, $method, $json);
     }
 
     /**
diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/EDS/QueryBuilder.php b/module/VuFindSearch/src/VuFindSearch/Backend/EDS/QueryBuilder.php
index d761481e70fc61ad5fda351856e2547008431d8c..240fde8cada6a4a80cc600df0232feef344e92a5 100644
--- a/module/VuFindSearch/src/VuFindSearch/Backend/EDS/QueryBuilder.php
+++ b/module/VuFindSearch/src/VuFindSearch/Backend/EDS/QueryBuilder.php
@@ -82,25 +82,20 @@ class QueryBuilder
      * @param Query  $query    Query to convert
      * @param string $operator Operator to apply
      *
-     * @return string
+     * @return array
      */
     protected function queryToEdsQuery(Query $query, $operator = 'AND')
     {
         $expression = $query->getString();
-        $expression = SearchRequestModel::escapeSpecialCharacters($expression);
         $fieldCode = ($query->getHandler() == 'AllFields')
             ? '' : $query->getHandler();  //fieldcode
         // Special case: default search
         if (empty($fieldCode) && empty($expression)) {
-            return $this->defaultQuery;
-        }
-        if (!empty($fieldCode)) {
-            $expression = $fieldCode . ':' . $expression;
-        }
-        if (!empty($operator)) {
-            $expression = $operator . ',' . $expression;
+            $expression = $this->defaultQuery;
         }
-        return $expression;
+        return json_encode(
+            ['term' => $expression, 'field' => $fieldCode, 'bool' => $operator]
+        );
     }
 
     /// Internal API
diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/EDS/SearchRequestModel.php b/module/VuFindSearch/src/VuFindSearch/Backend/EDS/SearchRequestModel.php
index bc69974b1f702cb21bd637c598c0e6ebf47b3e6b..4f5e1647671646222b9f90a43d5a6034efaae909 100644
--- a/module/VuFindSearch/src/VuFindSearch/Backend/EDS/SearchRequestModel.php
+++ b/module/VuFindSearch/src/VuFindSearch/Backend/EDS/SearchRequestModel.php
@@ -217,11 +217,25 @@ class SearchRequestModel
     {
         $qs = [];
         if (isset($this->query) && 0 < sizeof($this->query)) {
-            $qs['query-x'] = $this->query;
+            $formatQuery = function ($json) {
+                $query = json_decode($json, true);
+                $queryString = empty($query['bool'])
+                    ? '' : ($query['bool'] . ',');
+                if (!empty($query['field'])) {
+                    $queryString .= $query['field'] . ':';
+                }
+                $queryString .= static::escapeSpecialCharacters($query['term']);
+                return $queryString;
+            };
+            $qs['query-x'] = array_map($formatQuery, $this->query);
         }
 
         if (isset($this->facetFilters) && 0 < sizeof($this->facetFilters)) {
-            $qs['facetfilter'] = $this->facetFilters;
+            $formatFilter = function ($raw) {
+                list($field, $value) = explode(':', $raw, 2);
+                return $field . ':' . static::escapeSpecialCharacters($value);
+            };
+            $qs['facetfilter'] = array_map($formatFilter, $this->facetFilters);
         }
 
         if (isset($this->limiters) && 0 < sizeof($this->limiters)) {
@@ -233,7 +247,7 @@ class SearchRequestModel
         }
 
         if (isset($this->includeFacets)) {
-            $qs['includefacets']  = $this->includeFacets;
+            $qs['includefacets'] = $this->includeFacets;
         }
 
         if (isset($this->sort)) {
@@ -266,6 +280,95 @@ class SearchRequestModel
         return $qs;
     }
 
+    /**
+     * Converts properties to a search request JSON document to send to the EdsAPI
+     *
+     * @return string
+     */
+    public function convertToSearchRequestJSON()
+    {
+        $json = new \stdClass();
+        $json->SearchCriteria = new \stdClass();
+        $json->RetrievalCriteria = new \stdClass();
+        $json->Actions = null;
+        if (isset($this->query) && 0 < sizeof($this->query)) {
+            $json->SearchCriteria->Queries = [];
+            foreach ($this->query as $queryJson) {
+                $query = json_decode($queryJson, true);
+                $queryObj = new \stdClass();
+                if (!empty($query['bool'])) {
+                    $queryObj->BooleanOperator = $query['bool'];
+                }
+                if (!empty($query['field'])) {
+                    $queryObj->FieldCode = $query['field'];
+                }
+                $queryObj->Term = $query['term'];
+                $json->SearchCriteria->Queries[] = $queryObj;
+            }
+        }
+
+        if (isset($this->facetFilters) && 0 < sizeof($this->facetFilters)) {
+            $json->SearchCriteria->FacetFilters = [];
+            foreach ($this->facetFilters as $currentFilter) {
+                list($id, $filter) = explode(',', $currentFilter, 2);
+                list($field, $value) = explode(':', $filter, 2);
+                $filterObj = new \stdClass();
+                $filterObj->FilterId = $id;
+                $valueObj = new \stdClass();
+                $valueObj->Id = $field;
+                $valueObj->Value = $value;
+                $filterObj->FacetValues = [$valueObj];
+                $json->SearchCriteria->FacetFilters[] = $filterObj;
+            }
+        }
+
+        if (isset($this->limiters) && 0 < sizeof($this->limiters)) {
+            $json->SearchCriteria->Limiters = [];
+            foreach ($this->limiters as $limiter) {
+                list($id, $values) = explode(':', $limiter, 2);
+                $limiterObj = new \stdClass();
+                $limiterObj->Id = $id;
+                $limiterObj->Values = explode(',', $values);
+                $json->SearchCriteria->Limiters[] = $limiterObj;
+            }
+        }
+
+        if (isset($this->actions) && 0 < sizeof($this->actions)) {
+            $json->Actions = $this->actions;
+        }
+
+        $json->SearchCriteria->IncludeFacets = $this->includeFacets ?? 'y';
+
+        if (isset($this->sort)) {
+            $json->SearchCriteria->Sort = $this->sort;
+        }
+
+        if (isset($this->searchMode)) {
+            $json->SearchCriteria->SearchMode = $this->searchMode;
+        }
+
+        if (isset($this->expanders) && 0 < sizeof($this->expanders)) {
+            $json->SearchCriteria->Expanders = $this->expanders;
+        }
+
+        if (isset($this->view)) {
+            $json->RetrievalCriteria->View = $this->view;
+        }
+
+        if (isset($this->resultsPerPage)) {
+            $json->RetrievalCriteria->ResultsPerPage = intval($this->resultsPerPage);
+        }
+
+        if (isset($this->pageNumber)) {
+            $json->RetrievalCriteria->PageNumber = intval($this->pageNumber);
+        }
+
+        $highlightVal = isset($this->highlight) && $this->highlight ? 'y' : 'n';
+        $json->RetrievalCriteria->Highlight = $highlightVal;
+
+        return json_encode($json, JSON_PRETTY_PRINT);
+    }
+
     /**
      * Verify whether or not a string ends with certain characters
      *
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EDS/QueryBuilderTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EDS/QueryBuilderTest.php
index 13f3d3e9f698ed4793ede631bd4bee04af1db478..5fc2cf24a3951837a80c35b1a0ef2e5e5b879274 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EDS/QueryBuilderTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/EDS/QueryBuilderTest.php
@@ -42,6 +42,21 @@ use VuFindSearch\Backend\EDS\QueryBuilder;
  */
 class QueryBuilderTest extends TestCase
 {
+    /**
+     * Given a response, decode the JSON query objects for easier reading.
+     *
+     * @param array $response Raw response
+     *
+     * @return array
+     */
+    protected function decodeResponse($response)
+    {
+        foreach ($response as $i => $raw) {
+            $response[$i] = json_decode($raw, true);
+        }
+        return $response;
+    }
+
     /**
      * Test special case for blank queries.
      *
@@ -51,11 +66,19 @@ class QueryBuilderTest extends TestCase
     {
         $qb = new QueryBuilder();
         $params = $qb->build(new \VuFindSearch\Query\Query());
+        $response = $params->getArrayCopy();
+        $response['query'] = $this->decodeResponse($response['query']);
         $this->assertEquals(
             [
-                'query' => ['(FT yes) OR (FT no)']
+                'query' => [
+                    [
+                        'term' => '(FT yes) OR (FT no)',
+                        'field' => null,
+                        'bool' => 'AND',
+                    ],
+                ]
             ],
-            $params->getArrayCopy()
+            $response
         );
     }
 
@@ -68,11 +91,23 @@ class QueryBuilderTest extends TestCase
     {
         // Set up an array of expected inputs (serialized objects) and outputs
         // (queries):
-        // @codingStandardsIgnoreStart
         $tests = [
-            ['advanced', ['AND,cheese', 'AND,SU:test']]
+            [
+                'advanced',
+                [
+                    [
+                        'term' => 'cheese',
+                        'field' => null,
+                        'bool' => 'AND',
+                    ],
+                    [
+                        'term' => 'test',
+                        'field' => 'SU',
+                        'bool' => 'AND',
+                    ]
+                ]
+            ]
         ];
-        // @codingStandardsIgnoreEnd
 
         $qb = new QueryBuilder();
         foreach ($tests as $test) {
@@ -83,7 +118,9 @@ class QueryBuilderTest extends TestCase
                 )
             );
             $response = $qb->build($q);
-            $this->assertEquals($output, $response->get('query'));
+            $this->assertEquals(
+                $output, $this->decodeResponse($response->get('query'))
+            );
         }
     }
 }