2010-06-23 3 views
6

Je souhaite que mes résultats de recherche soient classés par score, ce qu'ils font, mais le score est mal calculé. C'est-à-dire, pas nécessairement incorrectement, mais différemment que prévu et je ne sais pas pourquoi. Mon but est d'enlever ce qui change le score.Solr: fieldNorm différent par document, sans augmentation de document

Si j'effectue une recherche qui correspond à deux objets (ObjectA devrait avoir un score supérieur à ObjectB), ObjectB est renvoyé en premier. Disons, pour cet exemple, que ma requête est un terme unique: "pommes".

Titre de ObjectA: « les pommes sont les pommes » (2/3 termes) La description de
ObjectA: « Il y avait des pommes dans les pommes-pommes et maintenant les pommes sont allés toutes les pommes partout dans les pommes » (6/18 terms)
Le titre de l'objetB: "pommes sont super" (1/3 termes)
Description de l'objetB: "Il y avait des pommes dans la salle des pommes et maintenant les pommes se sont mal passées partout sur les pommes!" (4/18 termes)

Le champ de titre n'a pas de boost (ou plutôt, un boost de 1) et le champ de description a un boost de 0.8. Je n'ai pas spécifié d'amélioration de document via solrconfig.xml ou via la requête que je traverse. S'il y a un autre moyen de spécifier un boost de document, il y a une chance qu'il m'en manque un.

Après avoir analysé l'impression explain, il ressemble à ObjectA est calculer correctement un score supérieur à ObjectB, tout comme je veux, sauf pour une différence: le fieldNorm titre de ObjectB est toujours plus élevé que ObjectA de.


Suit l'impression explain. Juste pour que vous le savez: le champ titre est mditem5_tns et le champ de description est mditem7_tns:

ObjectB: 
1.3327172 = (MATCH) sum of: 
    1.0352166 = (MATCH) max plus 0.1 times others of: 
    0.9766194 = (MATCH) weight(mditem5_tns:appl in 0), product of: 
     0.53929156 = queryWeight(mditem5_tns:appl), product of: 
     1.8109303 = idf(docFreq=3, maxDocs=9) 
     0.2977981 = queryNorm 
     1.8109303 = (MATCH) fieldWeight(mditem5_tns:appl in 0), product of: 
     1.0 = tf(termFreq(mditem5_tns:appl)=1) 
     1.8109303 = idf(docFreq=3, maxDocs=9) 
     1.0 = fieldNorm(field=mditem5_tns, doc=0) 
    0.58597165 = (MATCH) weight(mditem7_tns:appl^0.8 in 0), product of: 
     0.43143326 = queryWeight(mditem7_tns:appl^0.8), product of: 
     0.8 = boost 
     1.8109303 = idf(docFreq=3, maxDocs=9) 
     0.2977981 = queryNorm 
     1.3581977 = (MATCH) fieldWeight(mditem7_tns:appl in 0), product of: 
     2.0 = tf(termFreq(mditem7_tns:appl)=4) 
     1.8109303 = idf(docFreq=3, maxDocs=9) 
     0.375 = fieldNorm(field=mditem7_tns, doc=0) 
    0.2975006 = (MATCH) FunctionQuery(1000.0/(1.0*float(top(rord(lastmodified)))+1000.0)), product of: 
    0.999001 = 1000.0/(1.0*float(1)+1000.0) 
    1.0 = boost 
    0.2977981 = queryNorm 

ObjectA: 
1.2324848 = (MATCH) sum of: 
    0.93498427 = (MATCH) max plus 0.1 times others of: 
    0.8632177 = (MATCH) weight(mditem5_tns:appl in 0), product of: 
     0.53929156 = queryWeight(mditem5_tns:appl), product of: 
     1.8109303 = idf(docFreq=3, maxDocs=9) 
     0.2977981 = queryNorm 
     1.6006513 = (MATCH) fieldWeight(mditem5_tns:appl in 0), product of: 
     1.4142135 = tf(termFreq(mditem5_tns:appl)=2) 
     1.8109303 = idf(docFreq=3, maxDocs=9) 
     0.625 = fieldNorm(field=mditem5_tns, doc=0) 
    0.7176658 = (MATCH) weight(mditem7_tns:appl^0.8 in 0), product of: 
     0.43143326 = queryWeight(mditem7_tns:appl^0.8), product of: 
     0.8 = boost 
     1.8109303 = idf(docFreq=3, maxDocs=9) 
     0.2977981 = queryNorm 
     1.6634457 = (MATCH) fieldWeight(mditem7_tns:appl in 0), product of: 
     2.4494898 = tf(termFreq(mditem7_tns:appl)=6) 
     1.8109303 = idf(docFreq=3, maxDocs=9) 
     0.375 = fieldNorm(field=mditem7_tns, doc=0) 
    0.2975006 = (MATCH) FunctionQuery(1000.0/(1.0*float(top(rord(lastmodified)))+1000.0)), product of: 
    0.999001 = 1000.0/(1.0*float(1)+1000.0) 
    1.0 = boost 
    0.2977981 = queryNorm 

Répondre

6

le problème est causé par l'égrappoir. Il étend les «pommes sont des pommes» aux «pommes appl sont des pommes appl», rendant ainsi le champ plus long. Comme le document B contient seulement 1 terme qui est en train d'être développé par le moteur de recherche, le champ reste plus court que le document A.

Cela résulte en différents champs fieldNorm.

+0

Pourriez-vous élaborer, ou éventuellement fournir un lien? Pourquoi le «stemmer» étendrait-il mon champ à quelque chose que ce n'est pas *? Cela semble contre-intuitif! :) – JMTyler

+0

Sauf si le premier "appl" que vous avez écrit était censé être "apple"? Après avoir examiné la possibilité d'endiguer, cela aurait du sens si les «pommes» étaient décomposées en leur racine. Alors - laissez-moi savoir si j'ai bien compris - vous dites que si je change toutes les références à "apple" et que je ne recherche que "apple", je devrais obtenir les résultats dans l'ordre que je veux. – JMTyler

+0

J'ai édité mon post, donc ça devrait être plus clair maintenant. Le stemmer utilise "appl" comme forme de racine pour "pomme" et "pommes". Donc, si vous désactivez le stemming, vous devriez obtenir le résultat attendu. Vous pouvez également exclure les termes en les ajoutant à protwords.txt et en modifiant le fichier schema.xml Jem

2

FieldNOrm est calculée de 3 composants - boost à temps index sur le terrain, coup de pouce à temps index sur le document et la longueur de champ. En supposant que vous ne fournissez aucun boost d'index, la différence doit être la longueur du champ.

Ainsi, puisque lengthNorm est plus élevé pour les valeurs de champ plus courtes, pour B d'avoir une valeur de fieldNorm supérieure pour le titre, il doit avoir plus petit nombre de jetons dans le titre que A.

Voir les pages suivantes pour un explication détaillée de notation Lucene:

http://lucene.apache.org/java/2_4_0/scoring.html http://lucene.apache.org/java/2_4_0/api/org/apache/lucene/search/Similarity.html

+0

+1 pour beaucoup de perspicacité - merci! Malheureusement, vous remarquerez dans mon article que j'ai indiqué quels sont les champs (et leurs longueurs). Les deux objets ont des titres avec 3 jetons et des descriptions avec 18 jetons.Le titre d'ObjectA a 2/3 jetons correspondants, ObjectB a 1/3 correspondant, et les descriptions correspondantes sont respectivement 6/18 et 4/18. Donc, si je comprends ce que vous dites, le lengthNorm ne devrait pas avoir d'effet. Puis-je demander - comment pourrais-je faire pour mettre en place des booster de temps-index? – JMTyler

+0

Désolé - Je pensais que votre exemple était composé et non les valeurs réelles. Dans ce cas, vous avez raison dans le fait que la longueur du champ ne devrait pas être un facteur. Vous pouvez définir des boosts dans Solr de différentes façons - Si vous utilisez SolrJ, je crois qu'il existe une méthode "setBoost" sur le SolrInputDocument. Mais si le Doc B recevait un coup de pouce, fieldNorm devrait être plus haut dans le champ de description. Vous pouvez également consulter Luke - il vous permet de reconstruire vos données de terrain indexées afin que vous puissiez voir ce qui est vraiment indexé. – KenE

+0

Non, pas inventé - juste tester les données. :) Je vais jeter un coup d'oeil au code et voir si quelque chose de suspect se passe avec les boosts de l'index-temps. Je vais probablement vérifier aussi Luke. Merci pour l'aide. – JMTyler

Questions connexes