编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

Django 如何实现全文检索?

wxchong 2024-06-19 22:23:53 开源技术 12 ℃ 0 评论

作者: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搜索引擎"功能。

安装依赖

  1. pip install django-haystack

  2. pip install whoosh

  3. pip install jieba

具体实现

前端建立搜索框(base.html)

  1. <form action="/search" method="get" class="navbar-form navbar-left" role="search">

  2. <div class="form-group">

  3. <input type="text" class="form-control" name="q" placeholder="输入搜索内容" value=""/>

  4. </div>

  5. <button type="submit" class="btn btn-defaul">

  6. <span class="glyphicon glyphicon-search"></span>

  7. </button>

  8. </form>

添加URL(urls.py)

urls.py中,添加如下内容到urlpatterns

  1. url(r'^search/', include('haystack.urls')),

这样,上一步骤中的action将会指向haystack.urls

建立模型(models.py)

我们将对此文章类中的title和text进行搜索

  1. class Article(models.Model):

  2. class Meta:

  3. verbose_name = u'文章'

  4. verbose_name_plural = u'文章'

  5. article_type = (

  6. (1, u'失恋'),

  7. (2, u'暗恋'),

  8. (3, u'异地恋'),

  9. (4, u'爱恋'),

  10. )

  11. author = models.ForeignKey(settings.AUTH_USER_MODEL)

  12. title = models.CharField(u'文章标题',max_length=200)

  13. text = models.TextField(u'文章内容')

  14. choose_type = models.IntegerField(u'板块选择',choices=article_type, default=article_type[0][0])

  15. created_time = models.DateTimeField(u'发布时间',default=timezone.now, editable=False)

  16. # article valid or invalid

  17. status = models.IntegerField(u'状态',default=1)

  18. image = models.ImageField(u'文章图片',upload_to='images/articleimg', blank=True)

  19. def __unicode__(self):

  20. return self.title

选定模型(search_indexes.py)

在models.py所在目录下,新建search_indexes.py,用来确定我们将选定那个class来建立索引。

  1. #! /usr/bin/python

  2. # -*- coding: utf-8 -*-

  3. from misslove.models import Article

  4. from haystack import indexes

  5. class ArticleIndex(indexes.SearchIndex, indexes.Indexable):

  6. text = indexes.CharField(document=True, use_template=True)

  7. def get_model(self):

  8. return Article

  9. def index_queryset(self, using=None):

  10. 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,并在文件中写入(请去除其中的"",由于模板语言冲突

  1. {{ object.title }}

  2. {{ object.text }}

其中的 titletext就是我们想要建立索引的文章标题和文章内容。

添加搜索引擎到项目中(whooshcnbackend.py)

由于whoosh搜索引擎无法对中文进行搜索,所以我们需要使用jieba分词来作为whoosh的ChineseAnalyzer,这样就必须对原有的代码进行修改。考虑到安全性以及可移植性,我们可以把 whoosh_backend.py拷贝到项目下再进行修改。

whoosh_backend.py拷贝到models.py所在的目录下,并将其重命名为whoosh_cn_backend.py,然后,在该文件中添加

  1. from jieba.analyse import ChineseAnalyzer

找到

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

然后将其修改为

  1. 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应用

  1. INSTALLED_APPS = (

  2. 'django.contrib.admin',

  3. 'django.contrib.auth',

  4. 'django.contrib.contenttypes',

  5. 'django.contrib.sessions',

  6. 'django.contrib.messages',

  7. 'django.contrib.staticfiles',

  8. 'misslove',

  9. 'haystack',

  10. )

指定haystack的搜索引擎为上一步骤中修改好的,集成了jieba分词的 whoosh_cn_backend.py,在settings.py的末尾添加如下代码

  1. HAYSTACK_CONNECTIONS = {

  2. 'default': {

  3. 'ENGINE': 'misslove.whoosh_cn_backend.WhooshEngine',

  4. 'PATH': os.path.join(BASE_DIR, 'whoosh_index'),

  5. },

  6. }

到此,整个搜索的配置工作就完成了。

建立索引(终端)

我们将建立索引,在终端中运行

  1. python manage.py rebuild_index

成功后,便会在项目根目录下增加一个 whoosh_index的目录

索引自动更新(settings.py)

settings.py中加入

  1. HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

这样,当我们成功新建一篇Article之后,服务器便会自动更新索引,将该文章的标题和内容加入到索引中。

搜索结果显示(search.html)

templates/search/路径下,新建search.html,作为搜索结果的前端展示页面。

限于篇幅,本处不贴代码,需要的自行前往本项目Github地址中的/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),输入以下语句

  1. from whoosh.index import open_dir

  2. ix = open_dir('whoosh_indexes')

  3. from pprint import pprint

  4. pprint(list(ix.searcher.documents))

成功的话将会打印出已经建立的全部索引。 参考链接:

题图:pexels,CC0 授权。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表