2012-02-13 6 views
16

Si tengo un documento con un campo multivalor en Solr, ¿los valores múltiples se califican de forma independiente o simplemente se concatenan y se califican como un campo grande? Espero que sean puntuados de manera independiente. Aquí hay un ejemplo de lo que quiero decir:Puntuación del campo solr multivalente

Tengo un documento con un campo para el nombre de una persona, donde puede haber varios nombres para la misma persona. Los nombres son todos diferentes (muy diferentes en algunos casos) pero todos son la misma persona/documento.

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

Persona 2: David Letterman

Persona 3: David Hasselhoff, David Michael Hasselhoff

Si Debía buscar "David". Me gustaría que todos estos tengan la misma posibilidad de un partido. Si cada nombre se califica independientemente, parece ser el caso. Si solo se almacenan y se buscan como un solo campo, David Bowie sería castigado por tener muchos más símbolos que los demás. ¿Cómo maneja Solr este escenario?

Respuesta

18

Puede simplemente ejecutar su consulta q=field_name:David con debugQuery=on y ver qué pasa.

Estos son los resultados (incluida la puntuación a través fl=*,score) ordenados según 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> 

Y esta es la explicación:

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

Los factores de puntuación aquí son:

  • termFreq: cómo a menudo es un término aparece en el documento
  • IDF: ¿con qué frecuencia aparece el término a través del índice de
  • fieldNorm: importancia del término, según el índice de tiempo de impulso y la longitud del campo

En su ejemplo, el fieldNorm hace la diferencia. Tiene un documento con termFreq inferior (1 en vez de 1,4142135) ya que el término aparece solo una vez, pero esa coincidencia es más importante debido a la longitud del campo.

El hecho de que su campo sea multiValuado no cambia la puntuación. Supongo que sería lo mismo con un solo campo de valor con el mismo contenido. Solr funciona en términos de longitud de campo y términos, entonces, sí, David Bowie es castigado por tener muchas más fichas que los demás. :)

ACTUALIZACIÓN
De hecho, creo David Bowie merece su oportunidad. Como se explicó anteriormente, el fieldNorm hace la diferencia. Agregue el atributo omitNorms=true a su campo text_ws en el schema.xml y reindexe.La misma consulta le dará el siguiente resultado:

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

Como se puede ver ahora los termFreq victorias y el fieldNorm no se tiene en cuenta en absoluto. Es por eso que los dos documentos con dos ocurrencias de David están en la parte superior y con el mismo puntaje, a pesar de sus diferentes longitudes, y el documento más corto con solo un partido es el último con el puntaje más bajo. Aquí está la explicación con 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> 
+0

gracias por el desglose detallado, eso es justo lo que necesitaba saber. ¿Hay alguna manera alternativa de indexar estos datos para que esos nombres se califiquen de manera más "justa"? – user605331

+1

@ user605331 ¡Echa un vistazo a mi respuesta actualizada, también le di la oportunidad a David Bowie! – javanna

+1

Omitir normas ayuda, pero no es una buena solución. Uno podría querer que fieldNorm se tenga en cuenta, pero aún tenga que usar campos multivalor. Así que tenemos que decidir entre estos dos :( –

3

podría utilizar Lucenes SweetSpotSimilarity para definir la meseta de longitudes que todos deben tener una norma de 1,0. esto podría ayudarte con tu situación, siempre y cuando estés buscando cosas como nombres, etc. lengthNorm no sirve de nada.

+0

Esto se ve prometedor. Sin embargo, se establece en el nivel IndexWriter, no para un campo específico, por lo que si tengo un campo grande de otro texto (tal vez una biografía o algo apropiado para el ejemplo aquí) entonces tendría que usar SweetSpotSimilarity para eso también, ¿no? – user605331

Cuestiones relacionadas