2011-11-15 16 views
7

yo uso siguiente filtro en el schema.xml:¿Cómo impulsar ngrams más largos en solr?

<filter class="solr.EdgeNGramFilterFactory" minGramSize="4" maxGramSize="15" side="front"/> 

¿Cómo puedo aumentar los N-gramas más largos? Por ejemplo, cuando busco "bookpage", un documento que contiene "bookpage" debe tener una clasificación mucho más alta que un documento con solo "book".

Respuesta

5

No conozco una forma de aumentar dinámicamente en función de la longitud del término (es decir, con un operador Function Query). Sospecho que no hay uno.

Dicho esto, a menudo quiero aproximarme a la lógica que está buscando: las coincidencias a más largo plazo merecen un peso semántico mayor.

Lo más habitual es que indexe el valor del texto en dos campos diferentes. Uno es un campo de texto mínimamente procesado sin ngrams. El otro es similar, pero también se procesa con ngrams.

Aquí hay algunos extractos de muestra de un esquema que he usado de esta manera. Para las búsquedas en este esquema, impulsaría el campo text en gran medida sobre el text_ngram. Por lo tanto, cualquier coincidencia con el campo text influiría en gran medida en la relevancia, mientras que las coincidencias con text_ngram aún pueden recoger resultados quizás relevantes.

<?xml version="1.0" encoding="UTF-8"?> 
<schema name="Sunspot Customized NZ" version="1.0"> 
    <types> 

    <!-- 
     A text type with minimal text processing, for the greatest semantic 
     value in a term match. Boost this field heavily. 
    --> 
    <fieldType name="text" class="solr.TextField" omitNorms="false"> 
     <analyzer> 
     <tokenizer class="solr.StandardTokenizerFactory" /> 
     <filter class="solr.StandardFilterFactory" /> 
     <filter class="solr.LowerCaseFilterFactory" /> 
     </analyzer> 
    </fieldType> 

    <!-- 
     Looser matches with NGram processing for substrings of terms and synonyms 
    --> 
    <fieldType name="text_ngram" class="solr.TextField" omitNorms="false"> 
     <analyzer> 
     <tokenizer class="solr.StandardTokenizerFactory" /> 
     <filter class="solr.StandardFilterFactory" /> 
     <filter class="solr.LowerCaseFilterFactory" /> 
     <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" /> 
     <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="6" side="front" /> 
     </analyzer> 
    </fieldType> 

    <!-- other stuff --> 

    </types> 
    <fields> 

    <!-- id, other scalar values --> 

    <!-- catch-all for the text and text_ngram types --> 
    <field name="text"  stored="false" type="text"  multiValued="true" indexed="true" /> 
    <field name="text_ngram" stored="false" type="text_ngram" multiValued="true" indexed="true" /> 

    <!-- various dynamicField definitions --> 

    <!-- sample dynamicField definitions for text and text_ngram --> 
    <dynamicField name="*_text" type="text" indexed="true" stored="false" multiValued="false" /> 
    <dynamicField name="*_text_ngram" type="text_ngram" indexed="true" stored="false" multiValued="false" /> 

    </fields> 

    <!-- copy text fields into my text and text_ngram catch-all fields --> 
    <copyField source="*_text" dest="text" /> 
    <copyField source="*_text" dest="text_ngram" /> 

</schema> 

Esto no es exactamente lo que está buscando, pero podría utilizar un enfoque similar.

Por ejemplo, cree una pequeña colección de tipos de campos intermedios procesados ​​con NGram, por ejemplo, de longitud 1-3, 4-6, 7-9, y bríndeles aumentos aumentados en consecuencia.

+0

wow, muchas gracias por este enfoque, no pensé en indexarlo varias veces :) ¿Cómo se llegó a esta solución? – ndee

+1

Realmente no recuerdo la primera vez que usé esta técnica, siento que es un enfoque bastante común en Solr. La directiva 'copyField' es una sugerencia bastante fuerte para este efecto. A menudo pienso en coincidencias de términos exactos como las que tienen el valor semántico más fuerte, donde sinónimos, ngrams, derivaciones, etc. son varios enfoques para "expandir" los resultados de búsqueda en caso de error en los términos exactos. –