4

Je construis une fonction de recherche pour un site web php en utilisant 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 obtiennent zéro résultat. Aussi, si un magasin s'appelle "Foo Bar" et que le visiteur est "FooBar", rien n'est trouvé.Comment trouver "FooBar" lors de la recherche "Foo Bar" dans Zend Lucene

J'ai essayé de seach pour « foobar ~ » (de seach floue), mais n'a pas trouvé d'articles appelé « Foo Bar »

est-il un moyen speciar de construire l'index ou de faire la requête?

Répondre

2

Option 1: Interrompez la chaîne de requête d'entrée en deux parties en différents points et recherchez-les. par exemple. Dans ce cas, la requête serait (+ fo + bar) OU (+ foo + bar) OR (+ foob + ar) Le problème est que cette tokenisation suppose qu'il y a deux jetons dans la chaîne de requête d'entrée. En outre, vous pouvez obtenir des résultats supplémentaires, éventuellement non pertinents, tels que les résultats de (+ foob + ar)

Option 2: Utiliser la segmentation n-gram lors de l'indexation et de l'interrogation. Alors que l'indexation des jetons pour "foo bar" serait fo, oo, ba, ar. Pendant la recherche 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 n-grammes en haut. Cela peut obtenir avec NGramTokenizer

+0

Op. 2 sonne bien, avez une idée de comment utiliser la tokenisation n-gram? merci – Daniel

0

Avez-vous essayé "* foo * AND * bar *" ou "* foo * OR * bar *"? Ça marche chez Ferret et je lis que c'est basé sur Lucene.

+0

cela fonctionne si le queri est FOO BAR et dans la base de données j'ai FOOBAR mais si vous cherchez FOOBAR et dans la DB vous avez FOO BAR, ça ne marche pas – Daniel

+0

A droite, mon erreur ... j'ai fou idée: essayez de mettre '*' entre chaque caractère "f * o * o * b * a * r" et définissez une limite de longueur de chaîne (si str_len> 5). Ou vous pouvez essayer de mettre des espaces entre les lettres majuscules et inférieures - alors vous allez séparer "FooBar" à "Foo Bar" - mais l'utilisateur doit mettre cette chaîne dans le cas de chameau. – klew

0

Si vous ne se soucient pas de la performance, l'utilisation WildcardQuery (performance est nettement moins bon):

new WildcardQuery(new Term("propertyName", "Foo?Bar")); 

Pour zéro ou plusieurs caractères, utilisez « * », zéro ou un caractère , utilisation '?'

Si les performances sont importantes, essayez d'utiliser BooleanQuery.

+0

si l'utilisateur recherche "foobar" et dans la base de données j'ai "foo bar" il n'y a aucun moyen pour le script de savoir où mettre "?" ou "*" – Daniel

1

Ajoutez manuellement des entrées d'index pour la plupart des confusions de noms courantes. Demandez à vos clients de les saisir sur un formulaire spécial.

Questions connexes