2011-11-15 17 views
7

Aşağıdaki filtreyi schema.xml dosyasında kullanıyorum:Solr içinde daha uzun ngramlar nasıl artırılır?

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

Daha uzun ngramları nasıl artırabilirim? Örneğin, "bookpage" için arama yaptığımda, "bookpage" içeren bir belgenin, yalnızca "book" ile bir belgeden çok daha yüksek bir dereceye sahip olması gerekir.

cevap

5

Süre uzunluğuna (yani, İşlev Sorgusu operatörüyle) dayalı olarak dinamik olarak yükseltme yapmanın bir yolunu bilmiyorum. Bir tane olmadığından şüpheleniyorum.

Bu, genellikle aradığınız mantığı yaklaştırmak istiyorum: uzun süreli eşleşmeler daha yüksek anlamsal bir ağırlamayı hak ediyor.

Genellikle, metin değerini iki farklı alana dizinlerim. Bir tanesi, ngramlar içermeyen minimal şekilde işlenmiş bir metin alanıdır. Diğeri benzer, ancak aynı zamanda ngramlarla işlenmiş.

Bu şekilde kullandığım bir şemanın bazı örnek alıntıları aşağıda verilmiştir. Bu şemaya yapılan aramalarda, text alanını text_ngram üzerinden ağır bir şekilde artırırdım. Böylece, text alanına karşı yapılan tüm eşleşmeler alaka düzeyini büyük ölçüde etkileyecektir, oysa text_ngram'a karşı yapılan maçlar belki de alakalı sonuçlar alabilir.

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

Tam olarak aradığınız şey bu değil, benzer bir yaklaşım kullanabilirsiniz. Örneğin, orta ölçekli NGram tarafından işlenmiş alan türlerinden oluşan küçük bir koleksiyon yaratın - örneğin 1-3, 4-6, 7-9 arası uzunluklarda - ve buna göre artırılmış artışlar verin.

+0

Vay, bu yaklaşım için çok teşekkür ederim, çok kez indekslemeyi düşünmedim :) Bu çözümle nasıl başardınız? – ndee

+1

Bu tekniği ilk defa kullandığımı gerçekten hatırlamıyorum - Solr'da oldukça yaygın bir yaklaşım gibi hissediyorum. "CopyField" yönergesi, bu etki için oldukça güçlü bir ipucudur. Sıklıkla kesin terim eşlerini, en iyi semantik değere sahip olarak düşünürüm; burada eşanlamlılar, ngramlar, köken vb. Kelimelerin, kesin terimlerle ilgili bir miss durumunda arama sonuçlarını "genişletmek" için çeşitli yaklaşımları vardır. –