0

The documentation of the search api module says, about postprocess processor:

Postprocess query

This is probably the rarest phase for processors to use, postprocessing the query after it has run to manipulate the search results in some way. A prominent example would be the "Highlight" processor, which highlights the search keywords in the returned results. But this phase could also be used, for example, to re-run the query completely with some changes in case no results were found the first time.

However, it doesn't explain how to re-run the query completely.

I've to implement exactly in the case described: I've a search api view, with a fulltext search exposed filter and some facets.

If the query returns no results, I need to re-run it with some changes on the conditions provided by one of the facet filters (the content type), before actually rendering the result page.

This must be done programmatically and not by user interaction.

I've checked the ProcessorInterface but the only relative method seems to be the function postprocessSearchResults(ResultSetInterface $results);.

Highligh, the only processor implementing a postprocess_query stage doesn't do anything similar at what I need to do.

Any idea how I could re-run the query? I'm on a D9 site. Alternative solutions to the problem would be useful too, I'm trying this way as the documentation gives the idea it is a possible solution.

1 Answer 1

0

I managed to do something, despite not being optimal: in the postprocessSearchResults when necessary I send a RedirectResponse with new search params thus "reloading" the page and "re-running the search.

  /**
 *
 * @SearchApiProcessor(
 *   id = "my_processor",
 *   label = @Translation("A label"),
 *   description = @Translation("A description"),
 *
 *   stages = {
 *     "postprocess_query" = 0,
 *   }
 * )
 */
class MyProcessor extends ProcessorPluginBase {

  //Skipped constructor and boilerplate code

  /**
   * {@inheritdoc}
   */
  public function postprocessSearchResults(ResultSetInterface $results) {
    if ($results->getResultCount()) {
      return;
    }

    $query = $results->getQuery();

    if ($query->getProcessingLevel() != QueryInterface::PROCESSING_FULL) {
      return;
    }

    $request = $this->requestStack->getMasterRequest();
    $request_query = $request->query;
    $sdm_empty_result_automatic_search = $request_query->has($this->requestQueryTag) ? $request_query->get($this->requestQueryTag) : FALSE;

    /*
     * Necessary to identify between user search and ones run by this class.
     * E.g. if the user is on "article", and does a new search, it must stay
     * on "articles" if there is any result.
     * However if there are no results, the class must redirect to the fist
     * content type and so on until all are searched
     *
     */
    $next_type_value = NULL;
    $condition_type_value = $this->sdmSearchQueryHelper->queryGetConditionValue($query);
    switch ($condition_type_value) {
      case 'prodotto':
        $next_type_value = 'scheda_espositore';
        $sdm_empty_result_automatic_search = TRUE;
        break;
      case 'scheda_espositore':
        $next_type_value = $sdm_empty_result_automatic_search ? 'article' : 'prodotto';
        break;
      case 'article':
        $next_type_value = $sdm_empty_result_automatic_search ? NULL : 'prodotto';
        break;
    }

    if (empty($next_type_value)) {
      return;
    }

    $query_params = [
      'search_api_fulltext' => $query->getOriginalKeys(),
      'sort_by' => 'title',
      'f' => ['content_type:' . $next_type_value],
    ];

    if ($sdm_empty_result_automatic_search) {
      $query_params[$this->requestQueryTag] = $this->requestQueryTag;
    }

    $response = new RedirectResponse(Url::fromRoute('<current>', [], ['query' => $query_params])
      ->toString());
    $response->send();

     /**
     * todo
     * can't use the following logic but had to do all the previous because I have overriden the default url_processor,
     * so there is always a "default" content type if none is selected.
      * So unfortunately I can't run a generic query to search for all the results.
      * For a "standard" search implementation the following one could be a good starting point
     */
    /*
    $original_query = $query->getOriginalQuery();
    $original_query->addTag($this->queryTag);
    $this->sdmSearchQueryHelper->addConditionToQuery($original_query, 'facet:type', ['type' => 'scheda_espositore']);
    $results = $original_query->execute();

    $items = $results->getResultItems();
    $iterator = $results->getIterator();
    */

  }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.