2010-01-15 19 views
2

Je voudrais rechercher un index Lucene avec les distances d'édition. Par exemple, disons, il y a un document avec un champ FIRST_NAME; Je veux que tous les documents dont le prénom est à 1 distance de distance, par exemple, 'john'.Recherche Lucene avec des distances d'édition précises

Je sais que Lucene supporte les recherches floues (FIRST_NAME: john ~) et prend un nombre entre 0 et 1 pour contrôler le flou. Le problème (pour moi) est que ce nombre ne se traduit pas directement par une distance d'édition. Et lorsque les valeurs dans les documents sont des chaînes courtes (moins de 3 caractères), la recherche floue a du mal à les trouver. Par exemple, s'il y a un document avec FIRST_NAME "J" et que je recherche FIRST_NAME: I ~ 0.0, je ne reçois rien.

Répondre

1

Si vous avez seulement besoin d'une distance d'édition de 1 et si le résultat peut contenir la correspondance exacte, vous pouvez utiliser le caractère générique à caractère unique dans le langage de requête. Si le nom est

john 

alors la requête qui lui correspond et tout terme dans une distance d'édition ressemblerait

?john OR j?ohn OR jo?hn OR joh?n OR john? OR ohn OR jhn OR joh OR ?ohn OR j?hn OR jo?n OR joh? 

Pour plus de cas plus complexes, vous pourriez avoir besoin d'obtenir une liste des termes l'index (en utilisant IndexReader.term()), gardez ceux qui sont à 1 distance d'édition, et recherchez l'un de ces termes.

4

Dans FuzzyQuery de Lucene, vous ne pouvez pas spécifier la distance extact. Vous pouvez spécifier la valeur de "flou" entre 0 et 1 où les valeurs plus proches de 0 indiquent une correspondance large et les valeurs plus proches de 1 indiquent une correspondance étroite. La formule pour "flou" est la suivante. (De Lucene en action)

http://bit.ly/9hDVuF

De cette formule, vous pouvez remonter à une approximative pour fuzziness valeur donnée de la distance. Donc, StackOverflow doit correspondre à StackUnderflow, ce qui est à une distance de 3, le flou requis sera d'environ 0,77.

+1

En regardant Lucene en Action, la formule qu'ils ont sur la page 93 est '1 - distance/min (textlen, targetlen)', mais cela ne peut pas être entièrement correct car il permet des valeurs inférieures à 0.0. Dans mes tests, la formule utilise en fait 'min (textlen, targetlen)' (contrairement à leur implémentation de LevensteinDistance, qui utilise '1 - distance/max (textlen, targetlen)'), ils doivent donc rendre impossible le retour de chaînes nécessitant plus de changements que la longueur de la chaîne plus courte. –