【问题标题】:Character folding for a Django haystack and whooshDjango 干草堆和嗖嗖声的字符折叠
【发布时间】:2014-01-09 05:39:40
【问题描述】:

我有一个基于 django 的应用程序,带有 haystack 和 whoosh 搜索引擎。我想提供与重音和特殊字符无关的搜索,以便我也可以通过使用不带特殊字符的单词来查找带有特殊字符的索引数据:

索引为:

'café'

搜索词:

'cafe'  
'café'

我已经编写了一个特定的 FoldingWhooshSearchBackend,它使用 StemmingAnalyzer 和 aCharsetFilter(accent_map),如以下文档中所述:

https://gist.github.com/gregplaysguitar/1727204

但是搜索仍然无法正常工作,即我无法使用“cafe”进行搜索并找到“café”。我使用以下方法查看了搜索索引:

from whoosh.index import open_dir
ix = open_dir('myservice/settings/whoosh_index')
searcher = ix.searcher()
for doc in searcher.documents():
    print doc

特殊字符仍在索引中。

我需要做一些额外的事情吗?是关于更改索引模板的吗?

【问题讨论】:

  • 仅供参考,我更新了这个要点,它适用于 Haystack 2.4.0 和 Whoosh 2.7.0。我不确定你的问题是什么,但我最初写它的方式相当脆弱,所以也许这就是问题所在。

标签: django search django-haystack whoosh


【解决方案1】:

我认为最好的方法是让 Haystack 创建架构以实现最大的前向兼容性,然后将 CharsetFilter 破解。

此代码适用于 Haystack 2.4.0 和 Whoosh 2.7.0:

from haystack.backends.whoosh_backend import WhooshEngine, WhooshSearchBackend
from whoosh.analysis import CharsetFilter, StemmingAnalyzer
from whoosh.support.charset import accent_map
from whoosh.fields import TEXT


class FoldingWhooshSearchBackend(WhooshSearchBackend):

    def build_schema(self, fields):
        schema = super(FoldingWhooshSearchBackend, self).build_schema(fields)

        for name, field in schema[1].items():
            if isinstance(field, TEXT):
                field.analyzer = StemmingAnalyzer() | CharsetFilter(accent_map)

        return schema


class FoldingWhooshEngine(WhooshEngine):
    backend = FoldingWhooshSearchBackend

【讨论】:

    【解决方案2】:

    您必须为您的模型编写Haystack SearchIndex 类。这就是您可以为搜索索引准备模型数据的方式。

    myapp/search_index.py 示例:

    from haystack import site
    from haystack import indexes
    
    class UserProfileIndex(indexes.SearchIndex):
        text = indexes.CharField(document=True)
    
        def prepare_text(self, obj):
            data = [obj.get_full_name(), obj.user.email, obj.phone]
            original = ' '.join(data)
            slugified = slugify(original)
            return ' '.join([original, slugified])
    
    site.register(UserProfile, UserProfileIndex)
    

    如果用户的姓名为café,您将找到他的个人资料,其中包含cafécafe 两个搜索词。

    【讨论】:

    • 谢谢!这似乎可以解决问题。但是,我已经在自定义后端使用了字符集过滤器和词干分析器。这个后端没用吗?
    • 不,搜索后端应该能够处理它。自定义 SearchIndex 是错误的方法,因为它不会对用户的输入数据做任何事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 2012-08-06
    相关资源
    最近更新 更多