Is there a way to know when a specific search result is a best bet

Created on 22 May 2025, about 2 months ago

Problem/Motivation

We'd like to visually distinguish between best bet results that have been boosted, versus the rest of the normal results.

Is it possible to have a flag that indicates whether each given search result was boosted as part of a best bet match?

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

πŸ’¬ Support request
Status

Active

Version

3.0

Component

User interface

Created by

πŸ‡ͺπŸ‡¨Ecuador jwilson3

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @jwilson3
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    To my knowledge there is not but can see it being a useful feature!

  • πŸ‡ͺπŸ‡¨Ecuador jwilson3

    Maybe there is heuristic approach, whereby the boost on the matched term field is so ridiculously high, you can safely group the bosted results as different from normal results from a numerical calculation. I wanted to see if there was an easy/known approach here. I haven't yet dug into the internals of how best bet works yet, but I presume architecturally it is similar to how other standard boosts work (maybe not though too).

  • πŸ‡«πŸ‡·France bedlam Lyon

    I was looking at this this morning. The module page mentions that it applies a class to results when using Search API Pages, and shows how to get the 'elevated' status form inside the set of results (i.e. for each item).

    I needed a class on the view row, and handled it like this (in a .theme file):

    
    use Drupal\views\ViewExecutable;
    
    /**
     * Implements hook_views_pre_render()
     */
    function mytheme_views_pre_render(ViewExecutable $view) {
      $view_id = $view->id();
      if ($view_id === 'sitewide_search' && $view->current_display === 'sitewide_search_page') {
        // hook_views_pre_render() appears to runs once per view (?); here we use
        // drupal_static to do our part only once.
        $processed = &drupal_static(__FUNCTION__, []);
        $cache_key = sprintf('%s:%s', $view_id, $view->current_display);
    
        if (isset($processed[$cache_key])) {
          return;
        }
    
        if ($view->query instanceof \Drupal\search_api\Plugin\views\query\SearchApiQuery) {
          $results = $view->query->getSearchApiResults();
          $result_items = $results->getResultItems();
    
          foreach ($view->result as $index => $row) {
            if (isset($result_items[$row->search_api_id])) {
              $row->bestbet_elevated = (bool) $result_items[$row->search_api_id]->getExtraData('elevated');
            }
          }
        }
    
        $processed[$cache_key] = TRUE;
      }
    }
    
    /**
     * Implements template_preprocess_views_view_list().
     */
    function mytheme_preprocess_views_view_list(&$variables) {
      $view = $variables['view'];
    
      if ($variables['view']->id() === 'sitewide_search' && $variables['view']->current_display === 'sitewide_search_page') {
        foreach ($variables['rows'] as $index => &$row) {
          $result_row = $variables['view']->result[$index];
    
          if ($result_row->bestbet_elevated) {
            $row['attributes']->addClass('search-api-elevated');
          }
        }
      }
    }
    
    

    The mytheme_views_pre_render() implementation tags the row as elevated. After that, pretty much anything is possible. For our purposes, we only needed to render a class on that basis, but it should be possible to do other things like render the elevated item using a different view mode etc.

Production build 0.71.5 2024