Kamelot Blog

Aller au contenu | Aller au menu | Aller à la recherche

samedi 30 avril 2011

sam
30
avr '11

Cette folie en moi

Le soleil brûle mes yeux

Et je revois ces images

qui m'arrachent le cœur

J'aimerai plus de douceur

que tout aille mieux

C'est pas l'envie qui me manque

C'est le cri de la démence

Cette folie en moi

Qui me met dans un sale état

mardi 5 avril 2011

mar
05
avr '11

Sphinx : sql_attr_multi ou attribut à valeurs multiple

L'attribut Multi-valued attribute (MVA) de sphinx est une petite merveille que j'ai enfin appréhendé.

Un exemple

des étudiants

Je pars sur un exemple fictif.

Si j'ai des fiches étudiants à indexer. Je peux ajouter des attribut pour les filtrer.

  • date de naissance
  • genre (m=1/f=2)
  • Année (1,2,3,4,5,6)
  • Section (latin-grec=1, électricité=2,...)

Dans tous ces attributs, pour une ressource donnée (pour un étudiant), je n'ai qu'une valeur possible.

pour n'avoir que les garçons j'aurais

filter=genre,1;

pour n'avoir que les sections math (code 4) et sciences (code 9) j'aurais

filter=section,4,9

Si je mets

filter=genre,1;filter=section,4,9

j'aurais les garçons d'une de ces sections.

Complétons l'exemple

Maintenant selon la section j'ai jusqu'à 15 tranches horaires en cours à options (à la carte).

Comme ces cours à option ont des durées variables, l'étudiant doit remplir ses 15 périodes.

En composant avec les 40 options proposées, il peut se retrouver avec 15 cours d'une période ou 3 de 5 périodes ou 2 de 5h + 5 de une ...

Je veux chercher (ca tombe bien j'ai sphinx)

Comment indexer cela si dans ma recherche je veux pouvoir trouver les étudiants qui ont pris une option de type "langue"

Imaginant que dans la liste j'en ai 4 :

  • anglais (code 15),
  • néerlandais (code 18),
  • allemand (code 19)
  • et espagnol (code 21).

Ce qui ne marchera pas (sans les MVA)

Avec sphinx on en peut pas passer plusieurs filtres et dire matcher ce qui passe au moins un de ces filtres

Avec sphinx tous les filtres seront appliqués

Donc je ne peux pas créer 15 attributs (un par tranche) et dire

 filter=attribut_1,15,18,19,21;filter=attribut_2,15,18,19,21;filter=attribut_3,15,18,19,21;....

Parce qu'il faudrait que TOUS les attributs soient matchant pour la liste et donc ne me donnerai que ceux qui ont pris les 4 options et que celles là

Je ne peux pas non plus créer 40 attributs (un par option).

filter=attribut_15,1;filter=attribut_18,1;filter=attribut_19,1;filter=attribut_21,1;

ne me donnerai que ceux qui ont pris les 4 options

Avec les MVA

C'est là que les MVA entrent en jeux.

On va avoir 1 attribut "options" et pour chaque ressource l'attribut va contenir plusieurs valeurs

Lors de la recherche on passe dans la query

 filter=attribut_options,15,18,19,21;

Sphinx va matcher toutes les ressources qui ont au moins une de ces valeurs parmis celles qui lui sont attribuées

Indexation avec des attributs MVA

Maintenant qu'on a la façon de "chercher" il faut encore voir comment indexer cela.

Un petit coup d'oeil sur la doc.

Sphinx

sql_attr_multi = ATTR-TYPE ATTR-NAME 'from' SOURCE-TYPE \
	[;QUERY] \
	[;RANGE-QUERY]
where ATTR-TYPE is 'uint' or 'timestamp' SOURCE-TYPE is 'field', 'query', or 'ranged-query' QUERY is SQL query used to fetch all ( docid, attrvalue ) pairs RANGE-QUERY is SQL query used to fetch min and max ID values, similar to 'sql_query_range'

Si j'ai bloqué tout un temps c'est parce que c'était trop simple.

J'utilise sql_query pour ma source d'indexation.

Il suffit de produire un champs avec des valeurs séparée par des virgules.

puis on met

sql_attr_multi = unit lenomduchamps from field

Et nous y voilà.

Il y a aussi moyen de demander une sous-requete avec FROM query ou ranged-query

sql_attr_multi = uint tag from query; SELECT id, tag FROM tags

Rien compris à mon exemple d'étudiant ?

En voici un autre.

J'ai une liste d'enregistrements, ces enregistrements sont qualifiés par des tags.

C'est à dire qu'on est pas dans un classement par catégories dans un arbre tout simple.

Chaque enregistrement peut être associés à plusieurs tags.

Admettons que j'aie les tag grand, beau, bleu, jaune, ....

J'ai besoin de trouver tous les grands et bleus de ma base

  id name
    ---
   5 bleu
   11 grand

je vais faire une MVA pour pouvoir faire une recherche filter:tag_id,5,11

Tags