Avec Drupal et Drupal 8 encore plus la recherche passe la plupart du temps par Search API, une interface qui se branche devant plusieurs moteur de base de données (SolR, ElasticSearch, Database...)
Le plus souvent on va faire nos pages de résultats de recherche à l'aide de Views (et du module Search views pour Drupal 7). Mais dans certains cas on va vouloir avoir plus la main sur la recherche et donc aller interroger Search API directement dans le code.
Initialisation de la requête
Chargement de l'index (ici, le nom machine est « contenu »)
// Chargement de l'index « contenu »
$query = Index::load('contenu')->query();
Définition de la requête recherchée
Terme sur lesquels vont être effectués la requête.
// On lancer la recherche sur « hello world »
$query->keys("hello world");
Mode de la requête
// Les différentes possibilités sont
// - « direct » => Requête directe
// - « terms » => Multiple words
// - « phrase » => Single phrase
$parse_mode = \Drupal::service('plugin.manager.search_api.parse_mode')->createInstance('direct');
// Optionnellement, on peut choisir un opérateur spécifique (OR ou AND)
$parse_mode->setConjunction('OR');
// Affectation du mode de la requête
$query->setParseMode($parse_mode);
Définitions des champs sur lesquels rechercher
Évidement c'est optionnel, par défaut la recherche se fera sur l'ensemble des champs « fulltext » contenus dans l'index.
// Recherche uniquement sur le champ « body »
$query->setFulltextFields(['body']);
// Recherche uniquement sur les champs « body » et « title »
$query->setFulltextFields(['body', 'title']);
Ajout de conditions supplémentaires
L'objet retourné par Index::load('contenu')->query(); est une query classique drupal, sur laquelle on peut effectuer les traitement classique que l'on peut faire sur n'importe quelle Query drupal8.
À noter ici que le nom des champs doit être celui que l'on renseigne dans l'index, ils peuvent être différents des noms des champs définis dans nos types de contenu.
Quelques exemples en vrac :
Condition sur un champ boolean
// le champ private doit être « TRUE »
$query->addCondition('private', TRUE);
Condition sur un champ « varchar »
// on veut que le contenu retourné soit un article ou un snippet
$query->addCondition('type', ['article', 'snippet'], 'IN');
Condition sur un champ date
À noter le format de date à utiliser : "Y-m-d\TH:i:s\Z"
$btf = \DateTime::createFromFormat('d/m/Y', '21/10/2015');
$date_formatted = $btf->format("Y-m-d\TH:i:s\Z")
// Date de création de l'article > date définie
$query->addCondition('created', $date_formatted, '>');
// Et l'inverse
$query->addCondition('created', $date_to, ');
Pagination
Gestion de la pagination identique à une requête classique
// Récupération des 20 premiers résultats.
Exécution de la requête et récupération des résultats
$results_set = $query->execute();
//Nombre de résultats retournés
$nb_results = $results_set->getResultCount()
// Récupération des entités
foreach ($results_set->getResultItems() as $item) {
$resultat = $item->getOriginalObject()->getValue();
}
Sources
Pas trouvé grand chose sur le sujet à part cette page dans la documentation sur drupal.org : https://www.drupal.org/docs/8/modules/search-api/developer-documentatio…
Si vous avez d'autres liens pouvant aider, je suis preneur.