Right way to add items to a ResultSet

Created on 25 May 2018, almost 7 years ago
Updated 8 December 2023, over 1 year ago

Hello,

First, thank you very much for this great module.

I'am using search api with the elastic search connector module.
I build an index with two datasource : node and user.

With a view based on the index, and facets added, when i filter results with a facet based on taxonomy terms attached to node, only nodes corresponding to the terms are filtered and so displayed.

I need to add to the ResultSet the user items who are the owner of the nodes filtered.

I succeed to perform this feature using the postQuery() method of the SearchApiElasticsearchBackend().

    $search_api_fields_helper = \Drupal::service('search_api.fields_helper');
    $index = $query->getIndex();
    $user_datasource = $query->getIndex()->getDatasource('entity:user');
    $items = $results->getResultItems();
    // Store all the user added to the results
    $user_ids_added = [];

    /** @var \Drupal\search_api\Item\ItemInterface $item */
    foreach ($items as $item) {
      $language = $item->getLanguage();
      $itemId = $item->getId();
      $values = [];
      $fieldUid = $item->getField('uid_1');
      if ($fieldUid) {
        $values = $fieldUid->getValues();
      }
      if (isset($values[0]) && !empty($values[0])) {
        $uid = $values[0];
        $user = User::load($uid);
        if ($user instanceof UserInterface) {
          if (!$user->hasRole('my_role')) {
            continue;
          }

          if (in_array($uid, $user_ids_added)) {
            continue;
          }
          $id = 'entity:user/' . $uid . ':' . $language;
          $new_item = $search_api_fields_helper->createItem($index, $id , $user_datasource);
          $results->addResultItem($new_item);
          $user_ids_added[$uid] = $uid;
        }
      }
    }

I would like know if there is a better way to programmatically create a new item, and especially build the $id needed.
$id = 'entity:user/' . $uid . ':' . $language;
This part seems to me slightly hacky ?

Best regards

💬 Support request
Status

Fixed

Version

1.0

Component

Documentation

Created by

🇫🇷France flocondetoile Lyon

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 States rsnyd

    Thank you for the fantastic module! I realize this issue is closed, but there is surprisingly little to be found on this, so I thought I would post my question in case others stumble across this post.

    When adding items to a ResultSet in this way, find find two issues. For me, I'm combining content nodes and commerce product entities in my search results. When using a particular search term, there are 130 matches. Since my page size is set to 48 items per page, these 130 are broken into 3 pages. I've tried using both the SearchApiSolrEvents::POST_EXTRACT_RESULTS and search_api.processing_results events and I have the same results with each.

    Problem #1: The items are added to each page of the results. Meaning, if I add an additional 3 items to the ResultSet in the EvenSubscriber, the first page has 51 items, the second page has 51 items, and the third page has 37 items. The last 3 items of each page are my additions. How might I add these 3 items to the initial ResultSet of 130 items so they are only shown on one page?

    Problem #2: The items are added to the end of the list of items for any page. I've used the $new_item->setScore(51); to manually set the score higher than all other items, but my additions remain at the bottom of the list. How do I modify the relevancy for these items so they move to the top of the ResultSet?

  • 🇺🇸United States rsnyd

    To all who may happen upon my previous comment, I've received a response on Drupal Slack from one of the project maintainers pointing me to the code from the Visitors Voice project here:

    https://www.drupal.org/project/visitorsvoice →

    This is a D7 project, but apparently contains the result modification logic I am looking for. Additionally, a final comment:

    "Basically, though, you’ll always need to index extra fields if you want to modify the search results in a seamless way (i.e., without messing up paging, sorting, facet counts, etc.)."

    I will post my results once I'm able to successfully implement the addition of items to my ResultSet.

Production build 0.71.5 2024