diff --git a/config/vufind/searches.ini b/config/vufind/searches.ini
index 3dc20f1133a559432909a7cf4ad3e522d3a9d29d..447696c215c76b37612d55384f54bc7525b00e90 100644
--- a/config/vufind/searches.ini
+++ b/config/vufind/searches.ini
@@ -319,12 +319,20 @@ CallNumber = callnumber-sort
 ;       set of authority records is used for recommendations; for example:
 ;           AuthorityRecommend:record_type:Heading* OR Topical*:source:FAST
 ;       limits record_type to strings starting with "Heading" or "Topical" and
-;       limits source to FAST.  A special field name of "__resultlimit__" may be
+;       limits source to FAST. A special field name of "__resultlimit__" may be
 ;       used to suppress authority results when the result set contains more items
 ;       than the number specified as the corresponding value (e.g. if you configure
 ;       AuthorityRecommend:__resultlimit__:50 then authority recommendations will
 ;       only display on result screens displaying fewer than 50 hits; by default,
-;       recommendations will always display). Filtering is optional.
+;       recommendations will always display). A special field name of "__mode__"
+;       may be used to control what type of suggestions are presented (default is
+;       both seealso and usefor results, but you can turn on just one of these
+;       options if desired; for example "__mode__:seealso" would only show "see
+;       also" results from records whose main headings match the current search
+;       terms while "__mode__:usefor" would show only main headings from records
+;       whose "use for" headings match the current search. You can use "__mode__:*"
+;       to turn on all options (but this is default behavior if no __mode__ is
+;       set). Filtering is optional.
 ; Channels
 ;       Display a link to the Channeled Browse functionality leading to channels of
 ;       records related to the current search.
diff --git a/module/VuFind/src/VuFind/Recommend/AuthorityRecommend.php b/module/VuFind/src/VuFind/Recommend/AuthorityRecommend.php
index 2505ad82193361bdca50281f2e4100288284b9e7..53e7935a0b72090a1b6f3cdefb2bbe98a96d6c94 100644
--- a/module/VuFind/src/VuFind/Recommend/AuthorityRecommend.php
+++ b/module/VuFind/src/VuFind/Recommend/AuthorityRecommend.php
@@ -94,6 +94,13 @@ class AuthorityRecommend implements RecommendInterface
      */
     protected $resultsManager;
 
+    /**
+     * Which lookup mode(s) to use.
+     *
+     * @var string
+     */
+    protected $mode = '*';
+
     /**
      * Constructor
      *
@@ -118,6 +125,8 @@ class AuthorityRecommend implements RecommendInterface
             if (isset($params[$i + 1])) {
                 if ($params[$i] == '__resultlimit__') {
                     $this->resultLimit = intval($params[$i + 1]);
+                } elseif ($params[$i] == '__mode__') {
+                    $this->mode = strtolower($params[$i + 1]);
                 } else {
                     $this->filters[] = $params[$i] . ':' . $params[$i + 1];
                 }
@@ -144,64 +153,70 @@ class AuthorityRecommend implements RecommendInterface
     }
 
     /**
-     * Called after the Search Results object has performed its main search.  This
-     * may be used to extract necessary information from the Search Results object
-     * or to perform completely unrelated processing.
+     * Perform a search of the authority index.
      *
-     * @param \VuFind\Search\Base\Results $results Search results object
+     * @param array $params Array of request parameters.
      *
-     * @return void
+     * @return array
      */
-    public function process($results)
+    protected function performSearch($params)
     {
-        $this->results = $results;
-
-        // function will return blank on Advanced Search
-        if ($results->getParams()->getSearchType() == 'advanced') {
-            return;
-        }
-
-        // check result limit before proceeding...
-        if ($this->resultLimit > 0
-            && $this->resultLimit < $results->getResultTotal()
-        ) {
-            return;
-        }
-
-        // Build an advanced search request that prevents Solr from retrieving
-        // records that would already have been retrieved by a search of the biblio
-        // core, i.e. it only returns results where $lookfor IS found in in the
-        // "Heading" search and IS NOT found in the "MainHeading" search defined
-        // in authsearchspecs.yaml.
-        $request = new Parameters(
-            [
-                'join' => 'AND',
-                'bool0' => ['AND'],
-                'lookfor0' => [$this->lookfor],
-                'type0' => ['Heading'],
-                'bool1' => ['NOT'],
-                'lookfor1' => [$this->lookfor],
-                'type1' => ['MainHeading']
-            ]
-        );
-
         // Initialise and process search (ignore Solr errors -- no reason to fail
         // just because search syntax is not compatible with Authority core):
         try {
             $authResults = $this->resultsManager->get('SolrAuth');
             $authParams = $authResults->getParams();
-            $authParams->initFromRequest($request);
+            $authParams->initFromRequest(new Parameters($params));
             foreach ($this->filters as $filter) {
                 $authParams->addHiddenFilter($filter);
             }
-            $results = $authResults->getResults();
+            return $authResults->getResults();
         } catch (RequestErrorException $e) {
-            return;
+            return [];
         }
+    }
+
+    /**
+     * Return true if $a and $b are similar enough to represent the same heading.
+     *
+     * @param string $a First string to compare
+     * @param string $b Second string to compare
+     *
+     * @return bool
+     */
+    protected function fuzzyCompare($a, $b)
+    {
+        $normalize = function ($str) {
+            return trim(strtolower(preg_replace('/\W/', '', $str)));
+        };
+        return $normalize($a) == $normalize($b);
+    }
+
+    /**
+     * Add main headings from records that match search terms on use_for/see_also.
+     *
+     * @return void
+     */
+    protected function addUseForHeadings()
+    {
+        // Build an advanced search request that prevents Solr from retrieving
+        // records that would already have been retrieved by a search of the biblio
+        // core, i.e. it only returns results where $lookfor IS found in in the
+        // "Heading" search and IS NOT found in the "MainHeading" search defined
+        // in authsearchspecs.yaml.
+        $params = [
+            'join' => 'AND',
+            'bool0' => ['AND'],
+            'lookfor0' => [$this->lookfor],
+            'type0' => ['Heading'],
+            'bool1' => ['NOT'],
+            'lookfor1' => [$this->lookfor],
+            'type1' => ['MainHeading']
+        ];
 
         // loop through records and assign id and headings to separate arrays defined
         // above
-        foreach ($results as $result) {
+        foreach ($this->performSearch($params) as $result) {
             // Extract relevant details:
             $recordArray = [
                 'id' => $result->getUniqueID(),
@@ -211,12 +226,85 @@ class AuthorityRecommend implements RecommendInterface
             // check for duplicates before adding record to recordSet
             if (!$this->inArrayR($recordArray['heading'], $this->recommendations)) {
                 array_push($this->recommendations, $recordArray);
-            } else {
-                continue;
             }
         }
     }
 
+    /**
+     * Add "see also" headings from records that match search terms on main heading.
+     *
+     * @return void
+     */
+    protected function addSeeAlsoReferences()
+    {
+        // Build a simple "MainHeading" search.
+        $params = [
+            'lookfor' => [$this->lookfor],
+            'type' => ['MainHeading']
+        ];
+
+        // loop through records and assign id and headings to separate arrays defined
+        // above
+        foreach ($this->performSearch($params) as $result) {
+            foreach ($result->getSeeAlso() as $seeAlso) {
+                // check for duplicates before adding record to recordSet
+                if (!$this->fuzzyCompare($seeAlso, $this->lookfor)
+                    && !$this->inArrayR($seeAlso, $this->recommendations)
+                ) {
+                    array_push($this->recommendations, ['heading' => $seeAlso]);
+                }
+            }
+        }
+    }
+
+    /**
+     * Is the specified mode configured to be active?
+     *
+     * @param string $mode Mode to check
+     *
+     * @return bool
+     */
+    protected function isModeActive($mode)
+    {
+        return $this->mode === '*' || strpos($this->mode, $mode) !== false;
+    }
+
+    /**
+     * Called after the Search Results object has performed its main search.  This
+     * may be used to extract necessary information from the Search Results object
+     * or to perform completely unrelated processing.
+     *
+     * @param \VuFind\Search\Base\Results $results Search results object
+     *
+     * @return void
+     */
+    public function process($results)
+    {
+        $this->results = $results;
+
+        // function will return blank on Advanced Search
+        if ($results->getParams()->getSearchType() == 'advanced') {
+            return;
+        }
+
+        // check result limit before proceeding...
+        if ($this->resultLimit > 0
+            && $this->resultLimit < $results->getResultTotal()
+        ) {
+            return;
+        }
+
+        // see if we can add main headings matching use_for/see_also fields...
+        if ($this->isModeActive('usefor')) {
+            $this->addUseForHeadings();
+        }
+
+        // see if we can add see-also references associated with main headings...
+        if ($this->isModeActive('seealso')) {
+            $this->addSeeAlsoReferences();
+        }
+    }
+
     /**
      * Get recommendations (for use in the view).
      *
@@ -248,12 +336,8 @@ class AuthorityRecommend implements RecommendInterface
     protected function inArrayR($needle, $haystack)
     {
         foreach ($haystack as $v) {
-            if ($needle == $v) {
+            if ($needle == $v || (is_array($v) && $this->inArrayR($needle, $v))) {
                 return true;
-            } elseif (is_array($v)) {
-                if ($this->inArrayR($needle, $v)) {
-                    return true;
-                }
             }
         }
         return false;