2013-12-18 59 views
5

我有一個使用SOLR索引一個Django項目的子過濾器。Django的草垛 - 通過使用SearchQuerySet()字段

我試圖用草堆的SearchQuerySet類做字符串搜索

例如,當術語「耳朵」,它應該返回具有與值的字段條目的用戶搜索:「搜索」。 正如你所看到的,「耳朵」子串 「搜索」。 (顯然:))

換句話說,在一個完美的世界Django的,我想是這樣的:

SearchQuerySet().all().filter(some_field__contains_substring='ear') 

在草堆文檔SearchQuerySethttps://django-haystack.readthedocs.org/en/latest/searchqueryset_api.html#field-lookups), 它說,只有以下FIELD LOOKUP類型的支持:

  • 包含
  • 確切
  • GT,GTE,LT,LTE
  • startswith

我嘗試使用__ 包含,但它的行爲完全一樣 __exact,其查找範圍的精確的單詞(整個單詞)在一個句子中,而不是一個單詞的子串。

我很困惑,因爲這樣的功能是非常基本的,我不知道如果我失去了一些東西,或者有另一種方式來處理這個問題(使用正則表達式的東西?)。

感謝

回答

5

這可能使用EdgeNgramField現場進行:

some_field = indexes.EdgeNgramField() # also prepare value for this field or use model_attr 

那麼對於部分匹配:

SearchQuerySet().all().filter(some_field='ear') 
+3

謝謝!你的回答不是100%正確的,但它使我朝着正確的方向前進。解決方法是使用** NgramField **,而不是** EdgeNgramField **,如下所示:'some_field = indexes.NgramField(model_attr ='some_field')'。 ** EdgeNgramField **只能執行_「以」_和_「開始,並以」_ _類型的過濾結束。 – Nahn

+0

我沒有用Solr工作,但使用** NgramField **爲ElastiSearch工作。 –

+1

EdgeNgram字段不像'__contains'那樣工作,它通過基於莖的詞幹和查找其他匹配來工作,因此它會產生比包含更多的模糊結果集。 – shredding

0

這是在草堆中的錯誤。

正如您所說,__exact的實現方式與__contains完全相同,因此該功能在乾草堆中不存在。

的修復正在等待合併在這裏:https://github.com/django-haystack/django-haystack/issues/1041

可以彌合的等待時間固定的版本是這樣的:

from haystack.inputs import BaseInput, Clean 


class CustomContain(BaseInput): 
    """ 
    An input type for making wildcard matches. 
    """ 
    input_type_name = 'custom_contain' 

    def prepare(self, query_obj): 
     query_string = super(CustomContain, self).prepare(query_obj) 
     query_string = query_obj.clean(query_string) 

     exact_bits = [Clean(bit).prepare(query_obj) for bit in query_string.split(' ') if bit] 
     query_string = u' '.join(exact_bits) 

     return u'*{}*'.format(query_string) 

# Usage: 
SearchQuerySet().filter(content=CustomContain('searchcontentgoeshere'))