Comment trouver «FooBar» lors de la recherche de «Foo Bar» dans Zend Lucene
-
03-07-2019 - |
Question
Je construis une fonction de recherche pour un site web php avec Zend Lucene et j'ai un problème. Mon site Web est un directeur de magasin (quelque chose comme ça).
Par exemple, j'ai un magasin nommé "FooBar". mais mes visiteurs recherchent "Foo Bar" et obtenir des résultats nuls. De plus, si une boutique est nommée "Foo Bar" et les visites des visiteurs " FooBar " rien n'est trouvé.
J'ai essayé de rechercher " foobar ~ " (recherche floue) mais n’a pas trouvé d'article nommé "Foo Bar"
Existe-t-il un moyen spécifique de construire l'index ou d'effectuer la requête?
La solution
Option 1: coupez la chaîne de requête d'entrée en deux parties à différents endroits et recherchez-les. par exemple. Dans ce cas, la requête serait (+ fo + bar) OR (+ foo + bar) OR (+ foob + ar) Le problème est que cette tokénisation suppose qu'il y a deux jetons dans la chaîne de requête en entrée. Vous pouvez également obtenir des résultats supplémentaires, éventuellement non pertinents, tels que des résultats de (+ foob + ar)
Option 2: Utilisez la tokénisation n-gramme lors de l'indexation et de l'interrogation. Lors de l'indexation des jetons pour " foo bar " serait fo, oo, ba, ar. En cherchant avec foobar, les jetons seraient fo, oo, ob, ba, ar. La recherche avec OR en tant qu'opérateur vous donnera les documents avec un maximum de correspondances de n-grammes en haut. Cela peut être réalisé avec NGramTokenizer
Autres conseils
Ajoutez manuellement des entrées d'index pour les confusions de noms les plus courantes. Demandez à vos clients de les saisir sur un formulaire spécial.
Avez-vous essayé "* foo * AND * bar *"? ou "* foo * OR * bar *"? Cela fonctionne à Ferret et je lis que c'est basé sur Lucene.
Si vous ne vous souciez pas des performances, utilisez WildcardQuery (les performances sont nettement pires):
new WildcardQuery( new Term( "propertyName", "Foo?Bar" ) );
Pour zéro caractère ou plus, utilisez '*', pour zéro ou un caractère, utilisez '?'
Si les performances sont importantes, essayez d'utiliser BooleanQuery.