2011-06-14 118 views
7

我在使用solr作爲後端的項目中使用了haystack。我希望能夠執行包含搜索,類似於Django .filter(something__contains="...")使用Solr的Django-Haystack包含搜索

__startswith選項不適合我們的需要,因爲它如名稱所示,會查找以字符串開頭的單詞。

我試圖用類似*keyword*但Solr的不允許*用作第一個字符

感謝。

+0

是「關鍵字」一個單詞還是你想搜索部分單詞? – 2011-06-14 02:40:08

+0

其部分字 – neolaser 2011-06-14 03:45:21

+0

解決方案粘貼在這裏:http://stackoverflow.com/a/33260538/333566 – shredding 2015-10-21 13:25:55

回答

9

得到 「包含」 functionallity你可以使用:

<tokenizer class="solr.WhitespaceTokenizerFactory"/> 
<filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="100" side="back"/> 
<filter class="solr.LowerCaseFilterFactory" /> 

爲指標分析。

這將爲您的字段中的每個空白分隔的單詞創建ngram。例如:

"Index this!" => x, ex, dex, ndex, index, !, s!, is!, his!, this! 

正如你看到的,這將大大拓展你的索引,但如果你現在輸入一個查詢,如:

"nde*" 

它將匹配「ndex」給你一擊。

請謹慎使用此方法,以確保您的索引不會太大。如果增加minGramSize或減小maxGramSize,則不會將該索引擴展爲mutch,但會減少「contains」功能。例如,設置minGramSize =「3」將要求您的包含查詢中至少有3個字符。

+0

感謝您的答案和解釋,非常感謝! – neolaser 2011-06-14 23:18:40

0

我使用類似的表達式: .filter(something__startswith = '... ') .filter_or(NAME =' '+ S' ...') 原樣似乎Solr的不喜歡錶達喜歡' ... *',但與之結合或將會做

1

您可以實現相同的行爲,而無需觸摸solr模式。在您的索引中,使您的文本字段爲EdgeNgramField而不是CharField。在這種情況下,這會產生一個類似於lindstromhenrik建議的模式。

0

這裏的答案沒有一個真正的子字符串搜索*keyword*

他們沒有發現,是一個更大的字符串的一部分的關鍵詞,(不是前綴後綴)。

在索引使用EdgeNGramFilterFactoryEdgeNgramField只能做「startswith」或「的endsWith」類型的過濾。

的解決方案是使用一個NgramField這樣的:

class MyIndex(indexes.SearchIndex, indexes.Indexable): 
    ... 
    field_to_index= indexes.NgramField(model_attr='field_name') 
    ... 

這是非常優雅的,因爲你並不需要手動添加任何架構。xml