如何整合 Haystack+ElasticSearch+IK

让 HayStack + ElasticSearch 支持中文分词

  • 环境:
    • ubuntu 16.04
    • elasticsearch 2.4.6
    • django-haystack 2.8.1
    • IK Analysis for Elasticsearch 1.10.6
  • 要使用 es 5.X 需要 安装 django-haystack 开发版本。

安装

wget https://github.com/medcl/elasticsearch-analysis-ik/archive/v1.10.6.zip
unzip v1.10.6.zip
cd elasticsearch-analysis-ik-1.10.6
mvn clean   # 如果没有 mvn 可以 apt install mvn
mvn compile
mvn package

拷贝和解压 release下的文件: #{project_path}/elasticsearch-analysis-ik/target/releases/elasticsearch-analysis-ik-*.zip 到你的 elasticsearch 插件目录, 如: plugins/ik 重启 elasticsearch

  • 安装 Django-haystack
pip install django-haystack==2.8.1

以上步骤完成了各种组建的安装


接着,给 django-haystack 写个支持 ik 分词的 backend engine

  • 创建一个 elasticsearch_ik_backend.py 的文件, 加入一下代码
from haystack.backends.elasticsearch2_backend import Elasticsearch2SearchBackend
from haystack.backends.elasticsearch2_backend import Elasticsearch2SearchEngine


class IKSearchBackend(Elasticsearch2SearchBackend):
    DEFAULT_ANALYZER = "ik_max_word" # 这里将 es 的 默认 analyzer 设置为 ik_max_word

    def __init__(self, connection_alias, **connection_options):
        super().__init__(connection_alias, **connection_options)

    def build_schema(self, fields):
        content_field_name, mapping = super(IKSearchBackend, self).build_schema(fields)
        for field_name, field_class in fields.items():
            field_mapping = mapping[field_class.index_fieldname]
            if field_mapping["type"] == "string" and field_class.indexed:
                if not hasattr(
                    field_class, "facet_for"
                ) and not field_class.field_type in ("ngram", "edge_ngram"):
                    field_mapping["analyzer"] = getattr(
                        field_class, "analyzer", self.DEFAULT_ANALYZER
                    )
            mapping.update({field_class.index_fieldname: field_mapping})
        return content_field_name, mapping


class IKSearchEngine(Elasticsearch2SearchEngine):
    backend = IKSearchBackend

更新一下 django 的配置文件 settings.py 完成对 es 的中文分词的支持

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'path.to.elasticsearch_ik_backend.IKSearchEngine',
        'URL': 'http://es.example.com',
        'INDEX_NAME': 'ik_analysis',
        'BATCH_SIZE': 1000,
    },