Monitor Forum | Start New Thread Start New Thread
RE: Impact du tokenizer sur les filters de JDONREF [ Reply ]
By: Philippe Lagardère on 2015-02-25 10:53
[forum:482653]
Merci pour cette explication détaillée !

J'avais spontanément pensé au tokenizer d'Elasticsearch en oubliant complètement que le script Groovy utilisait un split sur le caractère "espace".

En suivant ta suggestion, j'arrive désormais bien à récupérer mon adresse avec une requête de type "8 almerad", ce qui répond tout à fait à nos attentes.

Pour limiter l'impact sur le script groovy, je n'ai pas utilisé la fonction tokenize() (qui renvoie une liste au lieu d'un array), mais simplement changé le paramètre en entrée de la méthode split(). Au lieu d'utiliser split(' '), j'utilise donc split(/(-| )/) pour scinder soit sur le tiret, soit sur l'espace.

De tête, je n'arrive pas à savoir s'il nous faudrait rajouter d'autres caractères à cette expression régulière, mais le cas échéant, la correction ne semble pas difficile !

RE: Impact du tokenizer sur les filters de JDONREF [ Reply ]
By: Julien Moquet on 2015-02-25 09:12
[forum:482652]
Le principe est le suivant :
1. le champ fullName crée une chaine composée des différents éléments de l'adresse à indexer ;
2. les tokenizers sont appliqués à cette chaine ;

Durant cette première étape, la chaîne est composée de la manière suivante :
1. je prend la ligne1, je la découpe suivant les espaces, je lui accole "|1" ;
2. je prend le numéro, je lui accole "|2" ;
3. je prend la répétition, je lui accole "|2" ;
4. je prend le type de voie, je le découpe par espace, je lui accole "|2";
5. je prend le libellé de voie, je le découpe par espace, je lui accole "|2";
etc ...

Si tu as bien compris, durant la construction du champ fullName, je n'ai pas tenu compte des tirets pour le découpage du champ concerné !
Le champ fullName est construit dans le mapping avec l'attribut transform.

Il s'agit d'un script groovy qui utilise la fonction split. Elle prend pour paramètre une regexp du découpage à effectuer.

A tester, mais si tu permutes avec la fonction "tokenize", tu peux spécifier l'ensemble des caractères pour lesquels un découpage doit être effectué.
(ex: http://mrhaki.blogspot.fr/2009/11/groovy-goodness-splitting-strings.html).

Pour obtenir quelque chose comme (cas des POIZON) :
"transform" : {
"lang" : "groovy",
"script" : "ctx._source['fullName'] = ; if (ctx._source['ligne7']!=null) { def tokens = ctx._source['ligne7'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|9'; }; if (ctx._source['code_pays']!=null) { def tokens = ctx._source['code_pays'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|10'; }; if (ctx._source['code_departement']!=null) { def tokens = ctx._source['code_departement'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|8'; }; if ( ctx._source['code_insee']!=null) { def tokens = ctx._source['code_insee'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|7'; }; if (ctx._source['code_insee_commune']!=null) { def tokens = ctx._source['code_insee_commune'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|6'; }; if (ctx._source['commune']!=null) { def tokens = ctx._source['commune'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|5'; }; if (ctx._source['code_arrondissement']!=null) { def tokens = ctx._source['code_arrondissement'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|4'; }; if (ctx._source['code_postal']!=null) { def tokens = ctx._source['code_postal'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|3'; }; if (ctx._source['numero']!=null) { ctx._source['fullName'] += ' ' + ctx._source['numero'] + '|11'; }; if (ctx._source['repetition']!=null) { def tokens = ctx._source['repetition'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|11'; }; if (ctx._source['type_de_voie']!=null) { def tokens = ctx._source['type_de_voie'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|2'; }; if (ctx._source['article']!=null) { def tokens = ctx._source['article'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|2'; }; if (ctx._source['libelle']!=null) { def tokens = ctx._source['libelle'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|2'; }; if (ctx._source['ligne1']!=null) { def tokens = ctx._source['ligne1'].tokenize(' -'); for(x in tokens) ctx._source['fullName'] += ' ' + x + '|1'; };"
}

A tester donc, puis je l'impacterai dans les prochaines révisions. Dis-moi si cela fonctionne !

Impact du tokenizer sur les filters de JDONREF [ Reply ]
By: Philippe Lagardère on 2015-02-24 18:26
[forum:482650]
Bonjour,

Nous sommes en train de vérifier l'adéquation de la recherche proposée par JDONREF, et nous avons un doute concernant les dénominations de voies utilisant un tiret.

L'exemple qui nous pose problème présentement est la RUE ABBE-ALMERAD, située à Digne-les-Bains (code insee 04070). Chez Google et OSM, la voie ne comporte pas de tiret, mais dans notre source de données le libellé est bien celui-ci.

En passant cette dénomination à l'analyzer "jdonrefv4_index", on constate que les tokens créés (avec le n-gram) sont :
a, ab, abe, abe-a, abe-al, et ainsi de suite jusqu'à abe-almerad. Et de fait, une recherche sur "8 almerad" ne trouve pas l'adresse, alors qu'un "8 hugo" va bien trouve le 8 BD VICTOR HUGO.

J'ai naïvement essayé de remplacer le tokenizer "whitespace" par "standard" dans les analyzes qui n'utilisaient que "whitespace". Cette fois-ci, l'analyzer crée bien deux tokens distincts (et d'ailleurs ne supprime plus les doubles consonnes), ce qui donne :
a, ab, abb, abbe
a, al, ... almerad

En revanche, la recherche semble ne plus marcher du tout, ce qui me laisse penser que le tokenizer joue un rôle ou dans la consolidation du champ fullName, ou dans la requête exploitant ce champ par la suite.

Comme c'est précisément un des pans de JDONREF qui m'échappent le plus, pourriez-vous m'aider à voir l'incidence de ce changement de tokenizer, et éventuellement me conseiller un moyen de résoudre mon problème ?

Merci d'avance !
Philippe

FEDER AQUINETIC Aquitaine Powered By FusionForge Collaborative Development Environment Charte d'utilisation / Nous contacter / Mentions légales Haut de page