Carnet Wiki

Utiliser l’API de recherche avec l’API SQL

Autrement dit : comment faire, en PHP et avec l’API SQL, des recherches équivalentes aux recherches faites en squelette avec le critère {recherche} ?

Pourquoi ?

Pour faire simple, en PHP on peut faire une query SQL ayant champ = 'ma recherche' ou bien champ LIKE '%ma recherche%'

Mais l’API de recherche présente des avantages, elle est optimisée :

  • Elle conserve les recherches en mémoire pour un résultat plus rapide
  • Elle sait dans quels champs rechercher et quel poids donner à chacun
  • Elle permet de classer les résultats en mettant les plus pertinents en premier
  • Elle bénéficie automatiquement des améliorations apportées par les plugins tels que Fulltext

Comment ?

include_spip('base/objets');
include_spip('base/abstract_sql');

// Le terme recherché
$search = _request('recherche');

// L'objet concerné par la recherche
$objet = 'article';
$table_objet_sql = table_objet_sql($objet); // spip_articles
$table_objet = table_objet($objet); // articles
$cle_objet = id_table_objet($objet); // id_article

// L'API de recherche fonctionne avec un alias `points` dans le SELECT, une jointure dans le FROM et une condition dans le WHERE
$prepare_recherche = charger_fonction('prepare_recherche', 'inc');
[$search_select, $search_where] = $prepare_recherche($search, $table_objet) ?: [];
$search_join = " INNER JOIN spip_resultats AS resultats ON (resultats.id = $table_objet_sql.$cle_objet)";

// Et la requête finale
$select = [$search_select, 'titre', 'date']; // ce qu'on veut en plus
$from = $table_objet_sql . $search_join; // pas le plus propre, exemple rapide
$where = [$search_where, 'statut = '.sql_quote('publie')]; // le statut publié dépend de chaque type d'objet, juste un exemple rapide
$groupby = $cle_objet;
$orderby = 'points DESC'; // résultats les plus pertinents en 1er
$collection = sql_allfetsel($select, $from, $where, $groupby, $orderby);
tcharlss - Mise à jour :28 juin 2023 à 00h01min