美文网首页马哥Linux运维原创作者投稿
如何为Django添加中文搜索服务

如何为Django添加中文搜索服务

作者: monkeyzhu | 来源:发表于2017-03-24 13:43 被阅读514次

    在使用python的过程中,必然会设计到如何创建web应用,而搜索功能却最为常见,该文档包含了如何整合haystack,elasticsearch、ik中文分词到django应用中。

    测试应用版本

    python 2.7.6
    elasticsearch 2.3.5
    elasticsearch-analysis-ik 1.9.5
    django==1.8.14
    django-haystack==2.6.0
    whoosh==2.7.4
    elasticsearch==5.1.0
    jieba==0.38

    安装

    python包安装

    更换pip安装源

    pip install django==1.8.14
    pip install haystack==2.4.1
    pip install whoosh==2.7.4
    pip install elasticsearch==5.1.0
    

    elasticsearch安装

    elasticsearch是基于java,所以java需要先安装

    [root@slave2 ~]# java -version
    java version "1.7.0_25"
    Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
    Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)
    [root@slave2 ~]# rpm -ivh https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/rpm/elasticsearch/2.3.5/elasticsearch-2.3.5.rpm
    [root@slave2 ~]# /etc/init.d/elasticsearch start
    [root@slave2 ~]# curl  http://localhost:9200/
    {
    "name" : "Titanium Man",
    "cluster_name" : "elasticsearch",
    "version" : {
    "number" : "2.3.5",
    "build_hash" : "90f439ff60a3c0f497f91663701e64ccd01edbb4",
    "build_timestamp" : "2016-07-27T10:36:52Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.0"
    },
    "tagline" : "You Know, for Search"
    }
    

    elasticsearch-analysis-ik安装

    安装maven

    wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo
    yum install apache-maven
    

    注意安装是使用对应的版本,测试也是如此,比如此处使用1.9.5版本。

    下载,安装elasticsearch-analysis-ik

    git clone https://github.com/medcl/elasticsearch-analysis-ik.git
    cd elasticsearch-analysis-ik
    git checkout v1.9.5
    mvn package # 需要先安装apache-maven工具
    ll target/releases/
    # 复制zip包到elasticsearch插件目录下 yum安装方式的默认路径 /usr/share/elasticsearch/
    cd /usr/share/elasticsearch/plugins/;mkdir ik;cd -
    cp target/releases/elasticsearch-analysis-ik-1.9.5.zip /usr/share/elasticsearch/ik/
    cd /usr/share/elasticsearch/ik/ ;unzip elasticsearch-analysis-ik-1.9.5.zip
    [root@slave2 ik]# ../../bin/plugin list
    Installed plugins in /usr/share/elasticsearch/plugins:
    -ik
    

    注意
    在使用中不用刻意选择高版本的elasticsearch,可以有效避免版本不兼容。另外一定要注意你使用的elasticsearch版本是否和elasticsearch-analysis-ik对应。可以参考该链接来对应好版本。
    测试文档

    # 重启elasticsearch 默认elasticsearch监听在localhost上
    # 如果是跨主机访问需要修改/etc/elasticsearch/elasticsearch.yml中network.host的配置。
    /etc/init.d/elasticsearch restart
    

    开始使用

    简单版本

    参考链接Django添加全文搜索功能入门篇使用whoosh作为后端索引存储(基于文件系统)
    按照该文档操作测试或者参考官方文档皆可。

    加入中文的支持

    #安装中文分词工具
    pip install jieba==0.38
    

    1、将文件haystack中的whoosh_backend.py(该文件路径为python安装路径下/lib/python2.7.6/site-packages/haystack/backends/whoosh_backend.py)拷贝到你创建的应用下面,并重命名为whoosh_cn_backend.py,例如blog/whoosh_cn_backend.py
    编辑blog/whoosh_cn_backend.py导入中文分析库ChineseAnalyzer

    from jieba.analyse import ChineseAnalyzer
    

    修改blog/whoosh_cn_backend.py大概163行位置

    schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(), field_boost=field_class.boost)
    

    2、在settings.py中修改之前使用的默认的whooshEngine为修改后的WhooshEngine。

    HAYSTACK_CONNECTIONS = {
        'default': {
            'ENGINE': 'blog.whoosh_cn_backend.WhooshEngine',
            'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
        },
    }
    

    3、重建索引python manage.py rebuild_index,在进行搜索中文试试吧。

    注意索引的自动更新:
    默认索引没有自动更新,那么每当有新数据添加到数据库,就要手动执行update_index命令是不科学的。自动更新索引的最简单方法在settings.py添加一个信号。

    HAYSTACK_SIGNAL_PROCESSOR = "haystack.signals.RealtimeSignalProcessor"
    

    升级版本

    由于whoosh是基于文件系统的,所有在索引数据量过大时必然引起性能问题。从官方描述也可以看得出Whoosh is pure Python, so it’s a great option for getting started quickly and for development, though it does work for small scale live deployments

    需要提前安装好elasticsearch和elasticsearch-analysis-ik,并通过测试。
    在之前的项目的基础上修改settings.py
    前:

    HAYSTACK_CONNECTIONS = {
        'default': {
            # 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
            'ENGINE': 'info_collect.whoosh_cn_backend.WhooshEngine',
            'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'),
        },
    }
    
    后:
    
    HAYSTACK_CONNECTIONS = {
        'default': {
            'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
            'URL': 'http://localhost:9200/', #多主机部署时需要修改elasticsearch的监听端口,之前提到过。
            'INDEX_NAME': 'haystack',
        },
    }
    

    创建索引名

    #创建索引名
    curl -XPUT http://localhost:9200/haystack
    
    # 重建索引
    python manage.py rebuild_index
    

    如果rebuild_index中出错,请仔细查看出错日志。

    部分代码

    urls.py:

    from django.conf.urls import url
    from haystack.query import SearchQuerySet
    from views import KeyWordSearchView
    from views import check_user_is_login
    
    qs = SearchQuerySet().order_by('keyword_ranking')
    
    ''' 加入需要登录认证的装饰器函数 check_user_is_login'''
    
    urlpatterns = [
    url(r'^search/', check_user_is_login(KeyWordSearchView(searchqueryset=qs, template='info_collect/search.html')), name='haystack_search'),]
    

    views.py:

    from haystack.views import SearchView
    
    class KeyWordSearchView(SearchView):
        ''' 为模板传递额外的参数 '''
        def extra_context(self):
            customer_id, user_name = get_current_user(self.request)
            return {'customer_id': customer_id, 'user_name': user_name}
    
        ''' 限制结果集 '''
        def get_results(self):
            return self.form.search()[:200]
    

    总结:

    通过对比两种方式,可以发现,whoosh使用jieba分词做处理,然后基于文件存储。elasticsearch使用ik分词作为插件,提供中文分词的能力,haystack通过下层抽象,在不修改代码的同时做到了可以选择不同后端索引存储的目的。

    参考链接:

    django官方网站
    haystack2.6文档
    Elasticsearch官方网站
    ik中文分词
    Django添加全文搜索功能入门篇

    相关文章

      网友评论

        本文标题:如何为Django添加中文搜索服务

        本文链接:https://www.haomeiwen.com/subject/shqfottx.html