社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Django

Django 如何实现全文检索?

编程派 • 8 年前 • 1168 次点击  


作者: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. action="/search" method="get" class="navbar-form navbar-left" role="search">

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

  •     class="glyphicon glyphicon-search">

  • 添加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 }}

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

    添加搜索引擎到项目中(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 授权。

    点击阅读原文,查看更多 Python 教程和资源。


    今天看啥 - 高品质阅读平台
    本文地址:http://www.jintiankansha.me/t/whZHsqqnMO
    Python社区是高质量的Python/Django开发社区
    本文地址:http://www.python88.com/topic/3089
     
    1168 次点击