Not working with search_api

Created on 25 August 2021, almost 3 years ago
Updated 10 November 2023, 8 months ago

I have the below setup:

Search_api view (with facets, but this is not relevant I think) setup as a block view.
A page (node) where the search_api block is shown through block layout.

The search_api view is setup to use the seed random order with a new seed every 60secs (as a test, on live website this would be 1hour), same seed for all users.

TEST 1:
I visit the page as anonymous user:
I can see the X-Drupal-Cache tag being set from the views_random_seed module.
I refresh immediately: the entire page is being fetched from cache. (OK)
I wait a few minutes and visit again: the entire page is being fetched from cache again, no new seed was generated. (not OK)

TEST 2:
I visit the page as admin (user 1) and bypass all caching. (same applies for another logged in user)
I can see the X-Drupal-Cache tag being set from the views_random_seed module.
The order of items in the view is different then that when viewed as anonymous user. (not OK)
I refresh immediately: the page is not fetched from cache, the order of items in the view has changed. (not OK)

Not sure how to debug this or get it fixed...

The cache-tags get added, so it seems like everything is working as expected.
I have debugged the search_api backend classes and I can also see that the correct options are set: "$this->setOption('search_api_random_sort', $params);" with the parameters from this module.

✨ Feature request
Status

Active

Version

1.0

Component

Code

Created by

πŸ‡§πŸ‡ͺBelgium weseze

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

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡¬πŸ‡§United Kingdom fonant

    Thanks @weseze for that code!

    I found that it duplicated the existing "random seed" sort I had added to the View, calling it random_order_field_2.

    That made the think that might be better to look for such a filter already existing, and to modify it, rather than adding a new filter to the view "behind the scenes".

    Here's my version of the code:

    /**
     * Implements hook_query_alter().
     */
    function random_seed_sort_db_query_alter(Drupal\Core\Database\Query\AlterableInterface $query) {
      // Modify any existing random_order_field sort.
      /** @var \Drupal\Core\Database\Driver\mysql\Select $query */
      $order_by = $query->getOrderBy();
      $needs_seed = (array_key_exists('random_order_field', $order_by));
      if ($needs_seed) {
        // Add random sorting with seed by manually calling the service.
        $options = [
          'id' => 'random_seed',
          'table' => 'views',
          'field' => 'random_seed',
          'relationship' => 'none',
          'group_type' => 'group',
          'admin_label' => NULL,
          'order' => 'ASC',
          'exposed' => NULL,
          'expose' => [
            'label' => NULL,
          ],
          'reuse_seed' => NULL,
          'user_seed_type' => 'same_per_user',
          'anonymous_session' => NULL,
          'reset_seed_int' => 0,
          'reset_seed_custom' => 3600, // time in seconds for the seed renewal.
          'plugin_id' => 'views_random_seed_random',
        ];
    
        /* @var $random_sort \Drupal\views_random_seed\Plugin\views\sort\ViewsRandomSeedRandom */
        $seed = \Drupal::service('views_random_seed.seed_calculator')
          ->calculateSeed(
            $options,
            'MYVIEWNAME', // This is not correct, but only important for cache tag naming.
            'MYDISPLAYNAME', // This is not correct, but only important for cache tag naming.
            \Drupal::database()->driver()
          );
        // Replace rand() with rand(seed).
        $expressions =& $query->getExpressions();
        $expressions['random_order_field']['expression'] = 'rand(' . $seed . ')';
      }
    }
    
    

    This works with MariaDB/MySQL, not sure if it's reliable for all databases.

  • πŸ‡«πŸ‡·France PhilY πŸ‡ͺπŸ‡ΊπŸ‡«πŸ‡· Paris, France

    Code from weseze at #7 updated by fonant at #9 works for me using Drupal 9.5.11 and Search API with a DB backend.
    This is a lifesaver for the project I need random sorting on a search page.

    I was wondering if it could be upgraded to get the actual reset_seed_custom value from the view itself rather than hard coding it in the custom code.

  • πŸ‡¬πŸ‡§United Kingdom fonant

    @PhilY I don't think that's possible, since we don't have direct access to the view in the query alter.

Production build 0.69.0 2024