一、Solr Multivalue field屬性positionIncrementGap理解
分類:
Lucene
2014-01-22 10:39閱讀(3596)評論(0)
參考:
http://rockiee281.blog.163.com/blog/static/19385222920127225619919/
Solr里頭可以設計Field為Multivalue類型,這樣的一個好處是可以很方便的設置copyField,在我們的項目中也有使用。
但是一直以來都有一個問題困擾着我,就是對multivalue里頭多個值域的搜索問題。多個value之間我認為應該是保持相互獨立的,但是在實際搜索中感覺solr把所有的值域都串在一起,當作一個長value來處理,沒有達到我想要的效果。后來通過搜索,我發現solr的field type中有一個positionIncrementGap字段,
,在網上看到一段討論:
http://lucene.472066.n3.nabble.com/positionIncrementGap-in-schema-xml-td488338.html。其中有人舉了一個例子:
一看之下大喜過望,這不是就是我想要的效果么 馬上去翻我solr的schema.xml的配置,一看我就涼了:
<fieldtype name="textComplex" class="solr.TextField" positionIncrementGap="100">
<analyzer type="query">
<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="dic">
</tokenizer>
<filter class="solr.SynonymFilterFactory" synonyms="synonyms_filter.txt" ignoreCase="true" expand="false"/>
<filter class="solr.StandardFilterFactory"/>
</analyzer>
<analyzer type="index">
<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="dic">
</tokenizer>
<filter class="solr.SynonymFilterFactory" synonyms="synonyms_filter.txt" ignoreCase="true" expand="false"/>
<filter class="solr.StandardFilterFactory"/>
</analyzer>
</fieldtype>
居然之前已經配置過了!!!那就是這個配置沒有生效,是什么造成的呢?因為我沒有使用solr自己的standardTokenizerFactory,而是為了中文分詞使用了MMSeg4J的類,我就把懷疑的目光放到了MMSeg4J身上。檢查了MMSegTokenizerFactory的源代碼,發現里頭木有對positionIncrementGap的處理,以為問題出在這里,但是在深入對比MMSegTokenizerFactory和StandardTokenizerFactory及相關的代碼類之后,感覺問題不應該出在建立索引的環節。
之后就是搜了一堆的資料,了解了positionIncrementGap這個字段的含義,其作用就是在對Multivalue Field進行處理的時候,給兩個field中相隔的詞人為的插入一段固定的distance,然后在使用Lucene/Solr做Phrase query的時候,如果沒有指定Slop(對slop的介紹,可以參考:http://blog.csdn.net/rick_123/article/details/6708527),會默認Slop為0,即查詢的短語之間應該緊緊挨着,這樣對很多情況下都得不到用戶想要的結果。解決的辦法就是使用phrase query,同時設置一個適當的Slop值,然后為了不讓lucene的搜索跨越多個Field Value,設置一個遠大於slop的positionIncrementGap,就可以達到目標。在這里不用擔心positionIncrementGap設置過大會影響效率,盡情的設吧……
既然了解positionIncrementGap的含義,問題就一目了然,樓主為了查詢的方便,使用自定的QueryParser替換了Solr自己默認的,將Phrase search改為了BooleanSearch,所以實際上導致了positionIncrementGap的失效。解決辦法就是將BooleanSearch改為MultiPhraseQuery,同時調用MultiPhraseQuery.setSlop(int slop)方法設置slop為50(經驗值,根據索引的數據設定,只要遠小於positionIncrementGap即可)。測試ok達到效果!
二、多值字段
針對多值字段,查詢表達式仍然會被拆分為一個一個的關鍵詞,然后去跨句子去匹配。
針對多值字段,查詢表達式仍然會被拆分為一個一個的關鍵詞,然后去跨句子去匹配。
三、動態字段
針對動態字段,查詢表達式可以精確查到句子,但是不能確保通配查詢。
針對動態字段,查詢表達式可以精確查到句子,但是不能確保通配查詢。
