web-dev-qa-db-fra.com

Renforcement de la correspondance exacte SOLR par rapport au texte contenant la correspondance exacte

Je n'ai pas pu trouver un meilleur titre, j'espère le changer plus tard si possible sur vos éventuelles suggestions.

Mon problème:

J'ai une base de données avec des artistes musicaux. Ils ressemblent à ceci: "dr. Dre feat. Akon", "eminem & dr. Dre", "dr. Dre feat. Ll cool j", "dr. Dre", "dr. Dre feat. Eminem & skylar grey" . Nous n'avons que deux champs: id et nom.

Sur un noyau solr de schéma par défaut, j'exécute cette requête: "q = dr. Dre" et les résultats sont corrects mais pas parfaits, ressemblant à ceci:

  • dr. dre feat. akon
  • eminem & dr. dre
  • dr. dre feat. ll cool j
  • dr. dre
  • ...

Notez qu'ils ont obtenu exactement le même score.

Ce que je veux, c'est avoir "dr. Dre" comme premier résultat, puis tous les autres, comme ceci:

  • dr. dre << - dr. dre est le premier
  • eminem & dr. dre
  • dr. dre feat. ll cool j
  • dr. dre feat. akon
  • ...

Comment puis-je y parvenir? (filtres, tokenizers, champs de copie, etc. ist n'a pas d'importance. Je ne peux pas changer le code dans solr comme je l'ai vu sur un autre forum suggéré)

Merci.

20
BogdanM

Il existe plusieurs façons d'obtenir le résultat "dr. Dre" en premier. Je m'excuse pour la longue réponse, mais comme cela arrive souvent dans Solr, la réponse dépend de vos priorités et de vos besoins.

C'est probablement redondant, mais je voudrais commencer par m'assurer que vous voyez les scores pour chaque résultat. Votre question n'a pas été très claire. Lorsque vous effectuez votre requête, vous devez explicitement dire à Solr de trier les résultats par ordre décroissant par leurs scores, bien que cela puisse être configuré dans le solrconfig.xml. J'imagine que vous le faites déjà, mais juste pour vous assurer, vous pouvez essayer une requête comme celle-ci: q="dr. dre"&fl=*,score&sort=score desc. Cela vous montrera le score calculé pour chaque résultat et triera d'abord les résultats avec les scores les plus élevés.

Normes

Les normes sont une option flexible qui fonctionne avec Solr assez naturellement. Votre champ name devrait probablement avoir une valeur type qui correspond à une entrée fieldType. fieldType devrait probablement avoir class="solr.TextField", et il ne devrait pas avoir omitNorms="true". Sauf si vous omettez explicitement des normes dans votre champ de nom, Solr considérera dans quelle mesure le nom correspond à vos termes de recherche et combien de fois vos termes de recherche correspondent dans le nom lors du calcul du score d'un document. "dr. dre" aurait le score le plus élevé car 100% des mots du nom correspondent à votre recherche.

Vous pouvez lire sur les normes et voir un bon texte général fieldType configuration sur le wiki de documentation Solr , ou dans votre documentation Solr téléchargée pour votre version particulière de Solr. L'avantage de s'appuyer sur des normes est qu'en plus d'être assez faciles à mettre en œuvre, elles sont progressives. Ainsi, alors que "dr. Dre" serait l'enregistrement correspondant à la plupart avec 100% de son nom correspondant à votre recherche, "eminem & dr. Dre" serait également plus pertinent que "toute une liste de gars et aussi dr. dre" car votre terme de recherche est une plus grande proportion du nom.

Correspondance exacte

La correspondance exacte est un problème compliqué dans Solr, en grande partie parce qu'il existe différents degrés d '"exactitude", et une correspondance vraiment exacte est rarement souhaitable dans la vie réelle. Par exemple, si votre dossier porte le nom "dr. Dre", "dr dre" (sans le point) est-il suffisamment proche pour être exact? Est-ce que "Dr. Dre"? Est-ce que "dr. Dre"?

Si vous décidez d'implémenter une recherche de correspondance exacte, vous souhaiterez probablement configurer un champ de copie dans votre schema.xml:

<copyField source="name" dest="exactName"/>

Ensuite, vous souhaiterez rechercher les deux champs ensemble. La façon dont vous procédez dépend de l'analyseur de requête que vous utilisez. Si vous utilisez l'analyseur de requête standard/lucene , vous devrez configurer vos requêtes avec OR recherche, (par exemple q=name:"dr. dre" OR exactName:"dr. dre"^4). Un "^ 4" après un terme de recherche rend cette correspondance 4 fois plus importante/pertinente qu'une correspondance ailleurs dans la requête. Si vous utilisez le parseur de requête Dismax ou Extended Dismax , vous avez accès au plus récent qf champ, qui vous permet de fournir une liste de champs à utiliser pour votre recherche, et de définir certains comme plus importants que d'autres. Par exemple qf=exactName^4 name&q="dr. dre" indique à Solr de rechercher "dr. dre" dans les deux champs, mais considère que la correspondance dans le champ exactName est 4 fois plus pertinente que celle dans le champ du nom. (Si cela fonctionne pour vous, la valeur par défaut qf peut être définie dans solrconfig.xml il n'est donc pas nécessaire de le retraiter à chaque requête.)

Cela laisse le fieldType du champ exactName indécis. Si vous pensez que seule une correspondance complètement précise fonctionnera et que des variations de majuscule ou de ponctuation rendent une correspondance non exacte, vous pouvez configurer le champ exactName sous forme de chaîne:

<field name="exactName" type="string" indexed="true" stored="false" multiValued="false"/>

Mais plus probablement, vous voudrez permettre une certaine variation de ce qui compte comme "exact", auquel cas vous devrez créer un nouveau fieldType, probablement en utilisant le Keyword Tokenizer , qui ne divisera pas le nom exact en plusieurs jetons indexés, mais le conservera comme un seul jeton. Par exemple:

<fieldType name="exactish" class="solr.TextField">
  <analyzer>
   <tokenizer class="solr.KeywordTokenizerFactory"/>
   <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer> 
</fieldType>

<field name="exactName" type="exactish" indexed="true" stored="false" multiValued="false"/>

Cet exemple très basique inclut uniquement le Tokenizer de mots clés pour conserver le nom entier en tant que jeton unique et le filtre de minuscules pour s'assurer que la différence entre les majuscules et les minuscules n'est pas pertinente. Si vous souhaitez que votre correspondance exacte pardonne toute autre condition, vous devrez modifier l'analyse pour le fieldType.

Important: lorsque vous effectuez une recherche par rapport à un champ de chaîne ou à un champ de texte contenant le mot-clé Tokenizer, il est judicieux de vous assurer que les recherches que vous envoyez à Solr a toujours des guillemets autour d'eux (c'est-à-dire la recherche de phrases). Sinon, votre recherche sera divisée en termes individuels avant d'être comparée au champ, et aucun un de vos termes ne correspondra probablement à l'ensemble du champ indexé. Cela peut conduire à ne jamais trouver de correspondance dans le champ, sauf lorsque les valeurs ne contiennent pas d'espaces de toute façon. Ce n'est pas un problème si vous utilisez simplement les normes pour contrôler la pertinence dans un textField avec une tokenisation plus standard.

36
frances