web-dev-qa-db-fra.com

Utiliser par programmation l'api de recherche

Je veux faire quelque chose comme ça

    $index = search_api_index_load("node_index");
    $myQuery=new SearchApiQuery($index);
    $myQuery->condition('type', 'blog', '=');
    $data=$myQuery->execute();
    $results=$data['results'];
    print_r($results);

mais pour Drupal 8, en utilisant l'api de recherche. Est-ce possible?

6
José Trindade
$query = Index::load('my_index')->query();
$query->addCondition('search_api_language', $language);
$query->keys($search_string);
$query->range(0, 25);
$data = $query->execute();

J'ai également une fonction d'analyse personnalisée pour les résultats:

function parse_results(array $results) {
$list = [];
  foreach ($results AS $item) {
    // The pattern is "entity:[entity_type]:[entity_id]:[language_code]".
    // For example "entity:node/1:en".
    $data = explode(':', $item->getId());
    $data = explode('/', $data[1]);
    $list[] = $data[1];
  }
  return $list;
}
5
user21641

Voici un résumé d'une idée sur laquelle je travaillais il y a quelques mois. Fondamentalement, un module personnalisé a un routeur (c'est-à-dire/search) et cela le gère. Je n'avais pas encore déménagé au point d'implémenter un formulaire de recherche personnalisé, mais cela m'a amené au point de départ d'une page avec des résultats et à un pager.

namespace Drupal\velirsearch\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Drupal\velirsearch\Service\PagerService;

class SearchResults extends ControllerBase {

  /**
   * @var \Drupal\velirsearch\Service\PagerService
   */
  private $pager_service;

  /**
   * SearchResults constructor.
   * @param \Drupal\velirsearch\Service\PagerService $pager_service
   */
  public function __construct(PagerService $pager_service) {
    $this->pager_service = $pager_service;
  }

  /**
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   * @return static
   */
  public static function create(ContainerInterface $container) {
    $pager_service = $container->get('velirsearch.pager_service');
    return new static($pager_service);
  }

  /**
   * @param \Symfony\Component\HttpFoundation\Request $request
   * @return array
   */
  public function build(Request $request) {
    /* @var $search_api_index \Drupal\search_api\IndexInterface */
    $index = $this->getSearchIndex('new_solr_test');

    // Create the query.
    $query = $index->query([
      'limit' => 10,
      'offset' => !is_null($request->get('page')) ? $request->get('page') * 10 : 0,
      'search id' => 'velirsearch:1',
    ]);

    if (!is_null($request->get('keyword'))) {
      $query->keys(['body' => $request->get('keyword'), '#conjunction' => 'AND']);
    }

    $results = $query->execute();

    $output = '';

    foreach ($results as $result) {
      $value = $result->getField('view_mode_teaser')->getValues();
      $output .= $value[0];
    }

    $render[] = [
      '#markup' => $output,
      '#type' => 'remote',
    ];

    $render[] = $this->attachPager($results->getResultCount(), 10);

    return $render;
  }

  /**
   * Title callback.
   *
   * @param Request $request
   *   The request.
   *
   * @return string $title
   *   The page title.
   */
  public function title(Request $request) {
    if (!is_null($request->get('keyword'))) {
      return $this->t('Search results for %keyword', ['%keyword' => $request->get('keyword')]);
    }

    return $this->t('Search results');
  }

  /**
   * Load and return a search index.
   * @param $id
   * @return \Drupal\Core\Entity\EntityInterface|null
   */
  protected function getSearchIndex($id) {
    return $this->entityTypeManager()->getStorage('search_api_index')->load($id);
  }

  /**
   * Convenient method to obtain a pager to attach from the pager service.
   * @param $totalRows
   * @param $limit
   * @return array
   */
  protected function attachPager($totalRows, $limit) {
    return $this->pager_service->getPager($totalRows, $limit);
  }
}

La méthode attachPager renvoie simplement:

pager_default_initialize($totalRows, $limit);
return ['#type' => 'pager'];

Je le séparais au cas où je souhaiterais créer plus d'une recherche personnalisée sans dupliquer l'ancien code de téléavertisseur.

Notez également que je concatène simplement la valeur d'un enregistrement dans Solr comme résultat, je stocke des rendus en mode vue dans Solr. Vous devrez probablement les rendre à la volée à moins que vous ne fassiez de même.

Cela a également été fait dans une version de l'API de recherche qui n'est pas à jour, YMMV. Mais cela a fonctionné pour moi.

5
Kevin

Le document officiel est ici: Exécution d'une recherche dans le code

Ce qui suit montre comment exécuter une recherche API de recherche par programme, avec un exemple de code:

$index = \Drupal\search_api\Entity\Index::load('INDEX_ID');
$query = $index->query();

// Change the parse mode for the search.
$parse_mode = \Drupal::service('plugin.manager.search_api.parse_mode')
  ->createInstance('direct');
$parse_mode->setConjunction('OR');
$query->setParseMode($parse_mode);

// Set fulltext search keywords and fields.
$query->keys('alea iacta');
$query->setFulltextFields(['title', 'name', 'body']);

// Set additional conditions.
$query->addCondition('status', 1)
  ->addCondition('author', 1, '<>');

// Add more complex conditions.
// (In this case, a condition for a specific datasource).
$time = \Drupal::service('datetime.time')->getRequestTime();
$conditions = $query->createConditionGroup('OR');
$conditions->addCondition('search_api_datasource', 'entity:node', '<>')
  ->addCondition('created', $time - 7 * 24 * 3600, '>=');

// Restrict the search to specific languages.
$query->setLanguages(['de', 'it']);

// Do paging.
$query->range(20, 10);

// Set additional options.
// (In this case, retrieve facets, if supported by the backend.)
$server = $index->getServerInstance();
if ($server->supportsFeature('search_api_facets')) {
  $query->setOption('search_api_facets', [
    'type' => [
      'field' => 'type',
      'limit' => 20,
      'operator' => 'AND',
      'min_count' => 1,
      'missing' => TRUE,
    ],
  ]);
}

// Set one or more tags for the query.
// @see hook_search_api_query_TAG_alter()
// @see hook_search_api_results_TAG_alter()
$query->addTag('custom_search');

// Execute the search.
$results = $query->execute();

echo "Result count: {$results->getResultCount()}\n";
$ids = implode(', ', array_keys($results->getResultItems()));
echo "Returned IDs: $ids.\n";
$facets = $results->getExtraData('search_api_facets', []);
echo 'Facets data: ' . var_export($facets, TRUE);
3
Tim Yao