Django 如何实现全文检索?
Posted 编程派
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django 如何实现全文检索?相关的知识,希望对你有一定的参考价值。
作者:chenyvehtung
原文:https://chenyvehtung.github.io/2015/09/11/django-haystack-search.html
背景介绍
本人在开发一个Django应用时,其中的一个需求是搜索功能,而Django本身并没有自带搜索模块,所以必须自己实现。显然,最简单粗暴的方法就是,通过暴搜数据库来查找接收到的文字输入,当数据量相对大一点时,这种方法是很不可取的。本文将要介绍的这个方法是使用Django-haystack这个全文检索框架结合Whoosh检索引擎以及Jieba(结巴)中文分词来实现的。
Whoosh是一个纯python实现的全文搜索组件。Whoosh不但功能完善,还非常的快。
Haystack是一个第三方的app,专门用来为Django增加全文检索功能,让你可以方便地对model里面的内容进行索引,搜索,简化你的工作。并且Django-haystack设计为支持whoosh,solr,Xapian,Elasticsearc四种全文检索引擎后端,属于一种全文检索的框架。
Jieba是一个Python中文分词组件,其包含多种功能,本文使用了其中的"ChineseAnalyzer for Whoosh搜索引擎"功能。
安装依赖
pip install django-haystack
pip install whoosh
pip install jieba
具体实现
前端建立搜索框(base.html)
<form action="/search" method="get" class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" name="q" placeholder="输入搜索内容" value=""/>
</div>
<button type="submit" class="btn btn-defaul">
<span class="glyphicon glyphicon-search"></span>
</button>
</form>
添加URL(urls.py)
在 urls.py
中,添加如下内容到 urlpatterns
url(r'^search/', include('haystack.urls')),
这样,上一步骤中的action将会指向haystack.urls
建立模型(models.py)
我们将对此文章类中的title和text进行搜索
class Article(models.Model):
class Meta:
verbose_name = u'文章'
verbose_name_plural = u'文章'
article_type = (
(1, u'失恋'),
(2, u'暗恋'),
(3, u'异地恋'),
(4, u'爱恋'),
)
author = models.ForeignKey(settings.AUTH_USER_MODEL)
title = models.CharField(u'文章标题',max_length=200)
text = models.TextField(u'文章内容')
choose_type = models.IntegerField(u'板块选择',choices=article_type, default=article_type[0][0])
created_time = models.DateTimeField(u'发布时间',default=timezone.now, editable=False)
# article valid or invalid
status = models.IntegerField(u'状态',default=1)
image = models.ImageField(u'文章图片',upload_to='images/articleimg', blank=True)
def __unicode__(self):
return self.title
选定模型(search_indexes.py)
在models.py所在目录下,新建search_indexes.py,用来确定我们将选定那个class来建立索引。
#! /usr/bin/python
# -*- coding: utf-8 -*-
from misslove.models import Article
from haystack import indexes
class ArticleIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
def get_model(self):
return Article
def index_queryset(self, using=None):
return self.get_model().objects.filter(status=1)
确定属性(article_text.txt)
此步骤中,我们需要建立 classname_text.txt
,并在其中指明我们需要对选定类中的哪些属性进行索引。该文件所在的路径应该是 templates/search/indexes/appname
。如本项目为: /templates/search/indexes/misslove/article_text.txt
,并在文件中写入(请去除其中的"",由于模板语言冲突)
{{ object.title }}
{{ object.text }}
其中的 title
和 text
就是我们想要建立索引的文章标题和文章内容。
添加搜索引擎到项目中(whooshcnbackend.py)
由于whoosh搜索引擎无法对中文进行搜索,所以我们需要使用jieba分词来作为whoosh的ChineseAnalyzer,这样就必须对原有的代码进行修改。考虑到安全性以及可移植性,我们可以把 whoosh_backend.py
拷贝到项目下再进行修改。
将 whoosh_backend.py
拷贝到 models.py
所在的目录下,并将其重命名为 whoosh_cn_backend.py
,然后,在该文件中添加
from jieba.analyse import ChineseAnalyzer
找到
schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=StemmingAnalyzer(), field_boost=field_class.boost, sortable=True)
然后将其修改为
schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(), field_boost=field_class.boost, sortable=True)
这样,便成功地为whoosh引擎添加了jieba分词
选定搜索引擎(settings.py)
我们需要在settings.py中添加haystack应用
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'misslove',
'haystack',
)
指定haystack的搜索引擎为上一步骤中修改好的,集成了jieba分词的 whoosh_cn_backend.py
,在 settings.py
的末尾添加如下代码
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'misslove.whoosh_cn_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
},
}
到此,整个搜索的配置工作就完成了。
建立索引(终端)
我们将建立索引,在终端中运行
python manage.py rebuild_index
成功后,便会在项目根目录下增加一个 whoosh_index
的目录
索引自动更新(settings.py)
在 settings.py
中加入
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
这样,当我们成功新建一篇Article之后,服务器便会自动更新索引,将该文章的标题和内容加入到索引中。
搜索结果显示(search.html)
在 templates/search/
路径下,新建 search.html
,作为搜索结果的前端展示页面。
其中的 page.object_list
是搜索之后的返回结果list,我们通过 result.object.attr
来获取我们所需要的属性。如本例中,我们使用 result.object.title
来获得返回的文章的标题。
至此,我们便成功地实现了基于django-haystack的全文搜索!
Debug相关
对于Haystack
需要对Haystack进行Debug时,可以参考其官方链接: Debugging Haystack
对于Whoosh
如果要查看whoosh_index中是否有正确存入索引, 可以在Django的shell中( python manage.py shell
),输入以下语句
from whoosh.index import open_dir
ix = open_dir('whoosh_indexes')
from pprint import pprint
pprint(list(ix.searcher().documents()))
成功的话将会打印出已经建立的全部索引。
参考链接:
题图:pexels,CC0 授权。
点击阅读原文,查看更多 Python 教程和资源。
以上是关于Django 如何实现全文检索?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Django Summernote 中显示编程片段的代码块?
Django全文检索实现:基于HayStack + Whoosh引擎 + Jieba中文分词