13.13.9 SearchDoc::addFilter()

La méthode addFilter permet d'ajouter un filtre sur les documents recherchés pour ne trouver qu'un sous-ensemble des documents.

13.13.9.1 Description

void addFilter(           string $filter, 
               string|int|double $…)

Cette méthode permet de configurer la requête SQL qui va être générée. Elle prend en argument un fragment de SQL et les associe pour créer la requête.

$searchDoc = new SearchDoc("", "IUSER");
$searchDoc->addFilter("title = '%s'", "my user");
$searchDoc->addFilter("id = %d", 12);

Les conditions SQL sont concaténés avec l'opérateur AND, par exemple la requête ci-dessus cherche les documents de type IUSER dont la propriété title est strictement égale à my user et la propriété id est égale à 12.

13.13.9.1.1 Avertissements

Les variables sont encodées avec la fonction pg_espace_string afin de construire correctement les filtres et afin d'éviter l'injection SQL.

Si les variables contiennent du texte, celui-ci doit être encodé en UTF-8.

Cette méthode n'est pas utilisable conjointement avec une recherche spécialisée en tant que collection de base.

13.13.9.2 Liste des paramètres

(string) filter

Partie filtre de la recherche, cette partie doit être soit une chaîne de caractères contenant du SQL, soit une chaîne formatée celle-ci est alors complétée avec les valeurs passées dans les arguments suivants. Attention : Les points suivants sont à prendre en compte :

  • injections SQL : le premier argument de la méthode addFilter est ajouté tel quel dans la requête SQL, il est donc possible qu'il puisse déclencher une injection SQL. Les données doivent être échappées (par exemple à l'aide de pg_escape_string),
  • gestion de la multiplicité : les valeurs des attributs multiples (premier et second niveau de multiplicité) sont stockées avec des caractères d'échappement. La création d'une requête les prenant en compte nécessite l'utilisation d'opérateurs propre à postgreSql, il existe plusieurs manières d'aborder le problème :

    • recherche à base d'expressions régulières : "ATTRNAME ~ E'\\\\y%s\\\\y'" : il faut remplacer ATTRNAME par le nom de l'attribut.
      Limitation : l'opérateur utilisé est une expression régulière avec le séparateur de mot \y cela peut engendrer des faux positifs si jamais la valeur contient elle-même des séparateurs de mot.
      Ce type de recherche permet de faire les filtres les plus simples (un parmi, etc.) avec le risque d'avoir des faux positifs.
    • recherche à base de conversion en array postgres, deux cas sont à prendre en compte :

      • l'attribut a 1 niveau de multiplicité : (regexp_split_to_array(ATTRNAME, E\'\\n\' ))
      • l'attribut a 2 niveaux de multiplicité : (regexp_split_to_array(replace(ATTRNAME, \'<BR>\', E\'\\n\'), E\'\\n\' ))

      Dans les deux cas, il faut remplacer ATTRNAME par le nom de l'attribut. Le comparaison se fait ensuite à l'aide des opérateurs propres aux tableaux.

      Ce type de recherche est plus coûteux en ressource que le premier type mais permet de faire des recherches plus complexes (a des éléments en commun, est contenu par, etc.) et limite le risque de faux positif.

(string|int|double) value
Valeurs qui sont concaténées à la partie filter à l'aide la fonction sprintf.
Note : Cet argument peut-être répété autant de fois que souhaité.
Attention : Les paramètres passés par value sont échappés à l'aide de la fonction pg_escape_string.
Attention : Dans le cas de l'utilisation d'un opérateur à base d'expression régulière, il faut utiliser la fonction preg_quote sans quoi les valeurs peuvent rendre l'expression régulière invalide.

13.13.9.3 Valeur de retour

void

13.13.9.4 Erreurs / Exceptions

Aucune.

13.13.9.5 Historique

Aucun.

13.13.9.6 Exemples

Recherche de documents dont l'attribut firstname est égal à "George" et l'attribut lastname à "Abitbol" :

$searchDoc = new SearchDoc("", "IUSER");
$searchDoc->addFilter("firstname = '%s' AND lastname = '%s'", "George", "Abitbol");

Recherche de documents dont l'attribut firstname est égal à "Arthur" et le lastname à "O'Connor" :

$searchDoc = new SearchDoc("", "IUSER");
$searchDoc->addFilter("firstname = '%s'", "Arthur");
$searchDoc->addFilter("lastname = '%s'", "O'Connor");

Recherche de documents dont la propriété titre commence par "La classe"

$searchDoc = new SearchDoc("", "FILM");
$searchDoc->addFilter("title ~* '^%s'", preg_quote("La classe"));

Note : On utilise ici l'opérateur ~* de postgresql.

Recherche de documents dont une des valeurs de l'attribut multivalué actors contient "John Wayne" :

$searchDoc = new SearchDoc("", "FILM");
$searchDoc->addFilter("actors ~* E'\\\\y%s\\\\y'", preg_quote("John Wayne"));

Attention : L'expression ci-dessus peut engendrer des faux positifs, par exemple, si acteur contient John Wayne Junior il est aussi trouvé car \y désigne un séparateur de mot et espace est un séparateur de mot.

Recherche de documents dont l'attribut multivalué actors contient John Wayne et Paul Newnam :

$searchDoc = new SearchDoc("", "FILM");
$searchDoc->addFilter("actors ~* E'\\\\y%s\\\\y'", preg_quote("John Wayne"));
$searchDoc->addFilter("actors ~* E'\\\\y%s\\\\y'", preg_quote("Paul Newnam"));

Attention : L'expression ci-dessus peut engendrer des faux positifs.

Recherche de documents dont l'attribut multivalué actors contient John Wayne et Paul Newnam :

$searchDoc = new SearchDoc("", "FILM");
$searchDoc->addFilter("ARRAY[$s] && (regexp_split_to_array(replace(actors, \'<BR>\', E\'\\n\'), E\'\\n\' ))", "'Paul Newnam', 'John Wayne'");

13.13.9.7 Notes

Aucunes.

13.13.9.8 Voir aussi

×