Оценка многозначного поля solr - программирование
Подтвердить что ты не робот

Оценка многозначного поля solr

Если у меня есть документ с многозначным полем в Solr, это несколько значений, набранных независимо или просто конкатенированные и занесенные как одно большое поле? Я надеюсь, что они выиграли независимо. Вот пример того, что я имею в виду:

У меня есть документ с полем для имени человека, где может быть несколько имен для одного и того же человека. Имена все разные (в некоторых случаях они очень разные), но все они - один и тот же человек/документ.

Лицо 1: Дэвид Боуи, Дэвид Роберт Джонс, Зигги Стардуст, Тонкий белый герцог

Лицо 2: Дэвид Леттерман

Лицо 3: Дэвид Хассельхофф, Дэвид Майкл Хассельхофф

Если бы я искал "Дэвида", я бы хотел, чтобы все они имели одинаковые шансы на матч. Если каждое имя забито независимо, что бы выглядело так. Если они просто хранятся и обыскиваются как одно поле, Дэвид Боуи будет наказан за то, что у него много других токенов, чем у других. Как Solr обрабатывает этот сценарий?

4b9b3361

Ответ 1

Вы можете просто запустить свой запрос q=field_name:David с помощью debugQuery=on и посмотреть, что произойдет.

Это результаты (включая оценку через fl=*,score), отсортированную по 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>

И это объяснение:

<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>

Факторы выигрыша здесь:

  • termFreq: как часто в документе появляется термин
  • idf: как часто этот термин появляется по индексу
  • fieldNorm: важность термина, в зависимости от повышения индекса и длины поля

В вашем примере fieldNorm имеет значение. У вас есть один документ с более низким termFreq (1 вместо 1.4142135), поскольку этот термин появляется только один раз, но это совпадение более важно из-за длины поля.

Тот факт, что ваше поле является multiValued, не меняет счет. Я предполагаю, что это будет одно и то же с одним полем значений с тем же контентом. Solr работает с точки зрения длины поля и условий, поэтому да, Дэвид Боуи наказан за то, что у него много других токенов, чем у других.:)

UPDATE
Я действительно думаю, что Дэвид Боуи заслуживает его возможности. Как описано выше, значение fieldNorm имеет значение. Добавьте атрибут omitNorms=true в поле text_ws в schema.xml и reindex. Тот же запрос даст вам следующий результат:

<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>

Как вы можете видеть, выигрыши termFreq и fieldNorm вообще не учитываются. Вот почему два документа с двумя встречами Дэвида находятся сверху и с одинаковым счетом, несмотря на их разную длину, а более короткий документ с одним матчем - последний с самым низким счетом. Здесь объяснение с помощью 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>

Ответ 2

вы можете использовать Lucenes SweetSpotSimilarity для определения плато длин, которое должно иметь норма 1.0. это может помочь вам в вашей ситуации, если вы ищете такие вещи, как имена и т.д. lengthNorm не приносит пользы.