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

在使用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添加全文搜索功能入门篇

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容

  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    aimaile阅读 26,440评论 6 428
  • 感觉网络上关于Django全文搜索的中文文章太少,并且讲的也不是很到位,就是简单介绍了怎么配置,并没有说这样配置有...
    tenlee阅读 8,000评论 3 16
  • GitHub 上有一个 Awesome - XXX 系列的资源整理,资源非常丰富,涉及面非常广。awesome-p...
    若与阅读 18,615评论 4 418
  • -------------记一篇对于电视剧的理解和我的生活。 选择不过是一时的激情。 这是beta说的。 当初...
    长安路人阅读 415评论 0 0
  • 在我的成长过程中,做过很多很有意思,也很有意义的梦。 在一些重要的人生关口,我的梦中便会开始有一个接一个的奇异的梦...
    书妍录阅读 416评论 0 1