Pointage du champ multivalué du solr

si j'ai un document avec un champ multivalué dans Solr les valeurs multiples sont-elles notées indépendamment ou simplement concaténées et notées comme un grand champ? J'espère qu'ils sont marqués de façon indépendante. Voici un exemple de ce que je veux dire:

j'ai un document avec un champ pour le nom d'une personne, où il peut y avoir plusieurs noms pour la même personne. Les noms sont tous différents (très différents dans certains cas) mais ils sont tous la même personne/document.

personne 1: David Bowie, David Robert Jones, Ziggy Stardust, Thin White Duke

personne 2: David Letterman

Personne 3: David Hasselhoff, David Michael Hasselhoff

si je devais chercher "David", j'aimerais que tout cela ait à peu près la même chance de correspondre. Si chaque nom est noté indépendamment, cela semble être le cas. S'ils sont simplement stockés et fouillés comme un seul champ, David Bowie serait puni pour avoir beaucoup plus de jetons que les autres. Comment ne Solr gérer ce scénario?

16
demandé sur user605331 2012-02-13 17:39:29

2 réponses

vous pouvez simplement lancer votre requête q=field_name:DaviddebugQuery=on et voir ce qui se passe.

ce sont les résultats (inclus le score par le biais de fl=*,score) triés par score desc:

<doc>
    <float name="score">0.4451987</float>
    <str name="id">2</str>
    <arr name="text_ws">
        <str>David Letterman</str>
    </arr>
</doc>
<doc>
    <float name="score">0.44072422</float>
    <str name="id">3</str>
    <arr name="text_ws">
        <str>David Hasselhoff</str>
        <str>David Michael Hasselhoff</str>
    </arr>
</doc>
<doc>
    <float name="score">0.314803</float>
    <str name="id">1</str>
    <arr name="text_ws">
        <str>David Bowie</str>
        <str>David Robert Jones</str>
        <str>Ziggy Stardust</str>
        <str>Thin White Duke</str>
    </arr>
</doc>

Et c'est l'explication:

<lst name="explain">
    <str name="2">
        0.4451987 = (MATCH) fieldWeight(text_ws:David in 1), product of: 1.0 = tf(termFreq(text_ws:David)=1) 0.71231794 = idf(docFreq=3, maxDocs=3) 0.625 = fieldNorm(field=text_ws, doc=1)
    </str>
    <str name="3">
        0.44072422 = (MATCH) fieldWeight(text_ws:David in 2), product of: 1.4142135 = tf(termFreq(text_ws:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 0.4375 = fieldNorm(field=text_ws, doc=2)
    </str>
    <str name="1">
        0.314803 = (MATCH) fieldWeight(text_ws:David in 0), product of: 1.4142135 = tf(termFreq(text_ws:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 0.3125 = fieldNorm(field=text_ws, doc=0)
    </str>
</lst>

La notation facteurs sont ici:

  • termFreq: combien de fois un terme apparaît dans le document
  • idf: combien de fois le terme apparaît à travers le index
  • fieldNorm: importance du terme, en fonction de l'index-gain de temps et de la longueur du champ

dans votre exemple le fieldNorm fait la différence. Vous avez un document avec les bas termFreq (1 au lieu de 1.4142135) puisque le terme n'apparaît qu'une seule fois, mais cette correspondance est plus importante en raison de la longueur du champ.

le fait que votre champ est multivalué ne change pas le pointage. Je suppose que ce serait la même chose avec un champ de valeur unique avec le même contenu. Solr fonctionne en termes de longueur de champ et de termes, donc, oui, David Bowie est puni pour avoir beaucoup plus de jetons que les autres. :)

UPDATE

Je pense que David Bowie mérite sa chance. Comme expliqué ci-dessus, le fieldNorm fait la différence. Ajouter l'attribut omitNorms=true pour votre text_ws champ schema.xml et réindexer. La même requête vous donnera ce qui suit: résultat:

<doc>
    <float name="score">1.0073696</float>
    <str name="id">1</str>
    <arr name="text">
        <str>David Bowie</str>
        <str>David Robert Jones</str>
        <str>Ziggy Stardust</str>
        <str>Thin White Duke</str>
    </arr>
</doc>
<doc>
    <float name="score">1.0073696</float>
    <str name="id">3</str>
    <arr name="text">
        <str>David Hasselhoff</str>
        <str>David Michael Hasselhoff</str>
    </arr>
</doc>
<doc>
    <float name="score">0.71231794</float>
    <str name="id">2</str>
    <arr name="text">
        <str>David Letterman</str>
    </arr>
</doc>

Comme vous pouvez le voir maintenant, le termFreq gagne et l' fieldNorm n'est pas prise en compte du tout. C'est pourquoi les deux documents avec deux occurences de David sont en haut et avec le même score, malgré leurs longueurs différentes, et le document plus court avec un seul match est le dernier avec le score le plus bas. Voici l'explication avec debugQuery=on:

<lst name="explain">
   <str name="1">
      1.0073696 = (MATCH) fieldWeight(text:David in 0), product of: 1.4142135 = tf(termFreq(text:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 1.0 = fieldNorm(field=text, doc=0)
   </str>
   <str name="3">
      1.0073696 = (MATCH) fieldWeight(text:David in 2), product of: 1.4142135 = tf(termFreq(text:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 1.0 = fieldNorm(field=text, doc=2)
   </str>
   <str name="2">
      0.71231794 = (MATCH) fieldWeight(text:David in 1), product of: 1.0 = tf(termFreq(text:David)=1) 0.71231794 = idf(docFreq=3, maxDocs=3) 1.0 = fieldNorm(field=text, doc=1)
   </str>
</lst>
19
répondu javanna 2012-02-20 19:02:42

vous pourriez utiliser la similarité des Lucenes Sweetspots pour définir le plateau de longueurs qui devrait tous avoir une norme de 1.0. cela pourrait vous aider avec votre situation aussi longtemps que vous êtes à la recherche de choses comme les noms, etc. lengthNorm ne fait pas de bien du tout.

3
répondu Simon Willnauer 2012-02-14 19:44:22