Advertisement

Python Django,全文检索,haystack框架,whoosh搜索引擎

阅读量:
  • haystack:一种专门设计的全文检索架构,在多个搜索引擎之间提供兼容性支持。
    • whoosh:一种基于Python开发的开源全文搜索引擎,在性能上略逊色于sphinx、Xapian和Elasticsearch等主流产品。尽管它不依赖二进制包运行(避免程序在无依赖情况下崩溃),但对于小型网站而言已经足够满足基本需求。
    • jieba:一款经过验证的免费中文分词工具(如果觉得不够好还可以选择付费版本)。

安装需要的包:

pip3 install django-haystack
pip3 install whoosh
pip3 install jieba

项目名/settings.py(配置设置,在该文件中进行注册并安装HAYSTACK应用程序,并对WHOOSH搜索引擎进行配置):

复制代码
  
    
 INSTALLED_APPS = (
    
     # ...
    
     'haystack',  # 安装应用haystack
    
 )
    
  
    
 # 配置搜索引擎
    
 HAYSTACK_CONNECTIONS = {
    
     'default': {
    
     # 使用whoosh引擎
    
     # 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',  # 对应whoost安装的路径
    
     'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',  # 使用jieba中文分词器
    
     # 索引文件路径
    
     'PATH': os.path.join(BASE_DIR, 'whoosh_index'),  # 索引文件的保存路径
    
     }
    
 }
    
  
    
 # 当添加、修改、删除数据时,自动生成索引
    
 HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
    
  
    
 # 指定搜索结果每页显示的条数 (默认20)
    
 HAYSTACK_SEARCH_RESULTS_PER_PAGE=15

项目名/urls.py(项目路由,配置全文检索的路由):

复制代码
 from django.conf.urls import include, url

    
  
    
 urlpatterns = [
    
     # ...
    
     url(r'^search', include('haystack.urls')),  # 将对应url请求交给全文检索框架。 ("/search"对应前端模板的搜索url)
    
 ]

建立索引

应用名/search_indexes.py(定义索引类,py文件名固定):

复制代码
 from haystack import indexes

    
 from 应用名.models import GoodsSKU  # 导入模型类 (要建立索引的模型类)
    
  
    
 # 定义索引类
    
 # 指定对于某个类的某些数据建立索引
    
 # 索引类名格式:模型类名+Index
    
 class GoodsSKUIndex(indexes.SearchIndex, indexes.Indexable):
    
     # text是一个索引字段。 use_template=True指定根据表中的哪些字段建立索引文件(使用下方创建的txt文件)
    
     text = indexes.CharField(document=True, use_template=True)
    
  
    
     def get_model(self):
    
     # 返回模型类
    
     return GoodsSKU
    
  
    
     # 建立索引的数据 (对哪些数据建立索引)
    
     def index_queryset(self, using=None):
    
     return self.get_model().objects.all()

templates/search/indexes/{ApplicationName}/{goodssku}_text.txt(配置该模型的小写字号文件中的字段到索引;指定目录为固定位置):

复制代码
 # 指定根据模型中的哪些字段建立索引数据

    
 {{ object.name }}  # 根据商品的名称建立索引
    
 {{ object.desc }}  # 根据商品的简介建立索引
    
 {{ object.goods.detail }}  # 根据商品的详情建立索引

创建索引文件: $ python manage.py rebuild_index # 该命令会在settings.py中指定的配置下生成索引文件。


使用索引

templates/demo.html(模板页,搜索框):

复制代码
 <!-- 。。。 -->

    
  
    
 <form method="get" action="/search">    <!-- 必须是get请求。 "/search"对应urls.py中配置的全文检索路由 -->
    
     <input type="text" name="q" placeholder="搜索商品">  <!-- name属性值必须是q。 q参数是关键字,page参数是第几页(haystack会自动分页) -->
    
     <input type="submit" value="搜索">
    
 </form>

在haystack系统中, 检索结果会被自动地传递到templates/search/search.html 模板中进行处理。

传递的模板变量如下:

query: 关键词
page: 当前页的对象(自动分段) –> 遍历 page 对象时会得到 SearchResult 类的具体实例,并且只有在 object 属性处才能找到对应的模型类实例。
paginator: 分页 paginator 实例用于分割页面内容

templates/search/search.html(模板,haystack自动返回的模板):

复制代码
 <!DOCTYPE html>

    
 <html lang="en">
    
 <head>
    
     <meta charset="UTF-8">
    
     <title>检索结果</title>
    
 </head>
    
 <body>
    
     搜索的关键字:{{ query }}<br/>
    
     当前页的Page对象:{{ page }}<br/>
    
     <ul>
    
     {% for item in page %}
    
         <li>{{ item.object }}</li>
    
     {% endfor %}
    
     </ul>
    
     分页paginator对象:{{ paginator }}<br/>
    
 </body>
    
 </html>

使用中文分词,jieba分词

jieba分词: $ pip3 install jieba # 安装jieba分词模块

demo.py(jieba分词器使用示例):

复制代码
 import jieba

    
  
    
 str = '要被分析的中文内容'
    
 res = jieba.cut(str, cut_all=True)
    
  
    
 for val in res:
    
     print(val)  # 要 被 分析 的 中文 内容

定位 haystack 安装的位置为 /home/用户名/.virtualenvs/虚拟环境名/lib/python3.5/site-packages/haystack/backends/

该目录下新建 ChineseAnalyzer.py 文件,内容如下:

复制代码
 import jieba

    
 from whoosh.analysis import Tokenizer, Token
    
  
    
 class ChineseTokenizer(Tokenizer):
    
     def __call__(self, value, positions=False, chars=False,
    
              keeporiginal=False, removestops=True,
    
              start_pos=0, start_char=0, mode='', **kwargs):
    
     t = Token(positions, chars, removestops=removestops, mode=mode, **kwargs)
    
     seglist = jieba.cut(value, cut_all=True)
    
     for w in seglist:
    
         t.original = t.text = w
    
         t.boost = 1.0
    
         if positions:
    
             t.pos = start_pos + value.find(w)
    
         if chars:
    
             t.startchar = start_char + value.find(w)
    
             t.endchar = start_char + value.find(w) + len(w)
    
         yield t
    
  
    
 def ChineseAnalyzer():
    
     return ChineseTokenizer()

复制该目录下的whoosh_backend.py 并改名为 whoosh_cn_backend.py。

修改 whoosh_cn_backend.py 中的内容:

复制代码
 # ...

    
  
    
 from .ChineseAnalyzer import ChineseAnalyzer  # 导入ChineseAnalyzer类
    
  
    
  
    
 # 查找
    
 # analyzer = StemmingAnalyzer()
    
 # 改为
    
 # analyzer = ChineseAnalyzer()
    
  
    
 # ...

项目名/settings.py(项目配置,搜索引擎使用whoosh_cn_backend):

复制代码
 # 配置搜索引擎

    
 HAYSTACK_CONNECTIONS = {
    
     'default': {
    
     # 使用whoosh引擎 (对应whoost安装的路径)
    
     # 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',  # whoost默认引擎
    
     'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',  # 使用jieba中文分词器
    
     # 索引文件路径
    
     'PATH': os.path.join(BASE_DIR, 'whoosh_index'),  # 索引文件的保存路径
    
     }
    
 }

**重新生成索引文件: $ python manage.py rebuild_index **

全部评论 (0)

还没有任何评论哟~