tutorial features example lucene solr

features - Marcador de Solr/Lucene



solr tutorial (4)

Actualmente estamos trabajando en una prueba de concepto para un cliente que usa Solr y hemos podido configurar todas las características que desean excepto la puntuación.

El problema es que quieren puntajes que hacen que los resultados caigan en pedazos:

  • Cubo 1: coincidencia exacta en la categoría (puntaje = 4)
  • Cubo 2: coincidencia exacta en el nombre (puntaje = 3)
  • Cubo 3: partido parcial en la categoría (puntaje = 2)
  • Cubo 4: coincidencia parcial en el nombre (puntaje = 1)

Lo primero que hicimos fue desarrollar una clase de similitud personalizada que devolviera la puntuación correcta según el campo y una coincidencia exacta o parcial.

El único problema ahora es que cuando un documento coincide tanto con la categoría como con el nombre, los puntajes se suman.

Ejemplo: buscar "restaurante" devuelve documentos en la categoría restaurante que también tienen la palabra restaurante en su nombre y así obtener un puntaje de 5 (4 + 1) pero solo deben obtener 4.

Supongo que para que esto funcione tendríamos que desarrollar una clase de puntuación personalizada, pero no tenemos idea de cómo incorporar esto en Solr. Otra opción es crear una implementación de SortField personalizada similar a RandomSortField ya presente en Solr.

Tal vez hay incluso una solución más simple que no conocemos.

Todas las sugerencias son bienvenidas!



El marcador es parte de las consultas de lucene a través del método de consulta ''peso''.

En resumen, el marco llama a Query.weight (..). Scorer (..). Mira esto

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

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

http://lucene.apache.org/jva/2_4_0/api/org/apache/lucene/search/Scorer.html

Para usar su propia clase Query en Solr, deberá implementar su propio solr QueryParserPlugin que use su propio QParser que genere su consulta lucene previamente implementada. Luego puede usarlo en Solr especificado aquí:

http://wiki.apache.org/solr/SolrPlugins#QParserPlugin

Esta parte de la implementación debería ser simple ya que es solo un código de pegado.

¡Disfruta hackeando Solr!


Puede anular la lógica que utiliza el marcador de soldadura. Solr usa la clase DefaultSimilarity para calificar.

  • Cree una clase que extienda DefaultSimilarity y anule las funciones tf (), idf (), etc. según su necesidad:

    public class CustomSimilarity extends DefaultSimilarity { public CustomSimilarity() { super(); } public float tf(int freq) { //your code return (float) 1.0; } public float idf(int docFreq, int numDocs) { //your code return (float) 1.0; } }

  • Después de crear la clase compilar y hacer un jar.
  • Coloque el archivo jar en la carpeta lib del índice o núcleo correspondiente.
  • Cambie schema.xml del índice correspondiente: <similarity class="<your package name>.CustomSimilarity"/>
  • Puede consultar varios factores que afectan la puntuación aquí

    Para su requerimiento, puede crear depósitos si su puntaje está en un rango específico. Lea también sobre el aumento de campo, el aumento de documentos, etc. Eso podría ser útil en su caso.


    Gracias por las buenas respuestas de arriba. Solo agregue a ellos, después de configurar esto en Solr 4.2.1, que permite la similitud por campo. (Antes de Solr 4, solo podía modificar la similitud para todos los campos de forma global).

    Digamos que queremos que Solr no use la frecuencia inversa del documento (idf) para un campo específico; deberíamos escribir nuestra propia Similitud personalizada para esto, como se mencionó anteriormente:

    package com.mycompany.similarity; import org.apache.lucene.search.similarities.DefaultSimilarity; public class NoIDFSimilarity extends DefaultSimilarity { @Override public float idf(long docFreq, long numDocs) { return 1.0f; } @Override public String toString() { return "NoIDFSimilarity"; } }

    y luego en nuestro schema.xml define un nuevo tipo de campo como este:

    <fieldType name="int_no_idf" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0" omitNorms="true"> <similarity class="com.mycompany.similarity.NoIDFSimilarity"/> </fieldType>

    y usarlo en un campo como este:

    <field name="tag_id_no_idf" type="int_no_idf" indexed="true" stored="false" multiValued="true" />

    Si hiciéramos solo esto, obtendría la siguiente excepción:

    SEVERE: Unable to create core: SimilarList org.apache.solr.common.SolrException: FieldType ''int_no_idf'' is configured with a similarity, but the global similarity does not support it: class org.apache.solr.search.similarities.DefaultSimilarityFactory at org.apache.solr.schema.IndexSchema.readSchema(IndexSchema.java:466) at org.apache.solr.schema.IndexSchema.<init>(IndexSchema.java:122) at org.apache.solr.core.CoreContainer.createFromLocal(CoreContainer.java:1018) at org.apache.solr.core.CoreContainer.create(CoreContainer.java:1051) at org.apache.solr.core.CoreContainer$3.call(CoreContainer.java:634) at org.apache.solr.core.CoreContainer$3.call(CoreContainer.java:629) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Apr 25, 2013 5:02:08 PM org.apache.solr.common.SolrException log SEVERE: null:org.apache.solr.common.SolrException: Unable to create core: SimilarList at org.apache.solr.core.CoreContainer.recordAndThrow(CoreContainer.java:1672) at org.apache.solr.core.CoreContainer.create(CoreContainer.java:1057) at org.apache.solr.core.CoreContainer$3.call(CoreContainer.java:634) at org.apache.solr.core.CoreContainer$3.call(CoreContainer.java:629) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: org.apache.solr.common.SolrException: FieldType ''int_no_idf'' is configured with a similarity, but the global similarity does not support it: class org.apache.solr.search.similarities.DefaultSimilarityFactory at org.apache.solr.schema.IndexSchema.readSchema(IndexSchema.java:466) at org.apache.solr.schema.IndexSchema.<init>(IndexSchema.java:122) at org.apache.solr.core.CoreContainer.createFromLocal(CoreContainer.java:1018) at org.apache.solr.core.CoreContainer.create(CoreContainer.java:1051) ... 10 more

    Una búsqueda en Google lo lleva a esto , así que simplemente agregue esta línea en su schema.xml, que se aplicará al resto de los campos:

    <similarity class="solr.SchemaSimilarityFactory"/>

    (Desde ese enlace: ¡Pero tenga en cuenta que coord y queryNorm (= 1.0f) no se implementan ahora, por lo que obtendrá puntuaciones diferentes para TF-IDF!)