zoukankan      html  css  js  c++  java
  • django-HayStack全局检索

    全文检索

    官方文档

    全文检索就是针对所有内容进行动态匹配搜索的概念

    针对特定的关键词进行建立索引精确匹配取出搜索结果,并且达到性能优化的目的

    • 为啥要有全文检索

    最常见的全文检索就是我们在数据库中进行的模糊查询

    但是模糊查询是针对整体内容的一个动态匹配过程,在数据量较大的情况下匹配效率极低

    常规项目中数据量一般都比较多并且内容繁杂,所以正常的项目搜索功能中很少会使用模糊查询进行操作

    如果你开发的项目用户量较少并且项目数据较少,那么此时模糊查询可以是你值得考虑的选项

    • django使用啥进行全文检索

    Python提供了各种模块进行全文检索,最常见的是haystack模块

    该模块设计为支持whooshsolrXapianElasticsearch 四种全文检索引擎后端

    使用haystack模块,不用更改代码,直接切换引擎,可以极大的减少代码量

    haystack属于一种全文检索的框架


    • whoosh

    Python编写的全文搜索引擎,是目前最快的python所编写的检索引擎,虽然性能比不上solrXapianElasticsearch等;但是无二进制包,程序不会莫名其妙的崩溃,对于小型的站点,whoosh已经足够使用

    • solr

    Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎

    Lucene:不是一个完整的全文检索引擎,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能

    • Xapian

    Xapian是一个用C++编写的全文检索程序,他的作用类似于Javalucene

    • Elasticsearch

    ElasticSearch是一个基于Lucene的搜索服务器它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口

    Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。该引擎常设计用于云计算中;能够达到实时搜索稳定可靠快速安装使用方便

    中文分词

    whoosh作为一个全文搜索引擎模块

    分词功能和检索功能已经非常强大,但是针对中文的处理还是比较欠缺

    可以通过Jieba模块重写分词操作,支持whoosh对中文的强大操作

    • 安装中文分词模块
    pip install jieba
    

    安装

    • 首先安装HayStack框架以及whoosh搜索引擎
    pip install django-haystack
    pip install whoosh
    

    settings配置

    • 添加haystack应用到项目的settings文件下的app部分
    INSTALLED_APPS = [
        'django.contrib.admin',
    	...
        'haystack',
    ]
    
    • 添加搜索引擎,这里使用whoosh引擎
    HAYSTACK_CONNECTIONS = {
        'default': {
            'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
            'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
        }
    }
    
    #这里使用django的信号机制,在数据表发生改动时自动更新whoosh的查询索引
    HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
    

    这里要注意的是,我们使用的引擎为whoosh_cn_backend

    本身的whoosh引擎名为:whoosh_backend

    whoosh_cn_backend将在接下来我们对安装目录下的引擎文件复制修改得来

    • 在项目的路由文件下配置查询的路由映射
    from django.urls import include,re_path
    urlpatterns = [
        path('admin/', admin.site.urls),
        re_path('^search/',include('haystack.urls')),
    ]
    

    当查询条件被提交时,会跳转至search路由

    并且查询条件会作为get请求时的连接参数传入,参数key值为q

    创建索引文件

    • 接下来,在需要被搜索的app下建立search_indexes.py文件,该文件名不许变更
    #app.models.py
    class User(models.Model):
        # 用户表
        name = models.CharField(
            max_length=50,
            verbose_name='昵称'
            )
        account = models.CharField(max_length=50,verbose_name='账号',unique=True)
        passwd = models.CharField(max_length=50,verbose_name='密码')
        def __str__(self):
            return self.name
    
    #app.search_indexes.py
    from haystack import indexes
    from . import models
    
    class UserIndex(indexes.SearchIndex, indexes.Indexable):
        text = indexes.CharField(document=True, use_template=True)
    
        def get_model(self):
            return models.User # 当前模型文件下需要被检索的模型类
    
        def index_queryset(self, using=None):
            return self.get_model().objects.all()
    

    该类为索引类,类名为模型类的名称+Index:比如模型类为People,则这里类名为PeopleIndex

    get_model函数用来获取当前索引类所关联的模型类,这里我们关联上面的User 类对象

    text=indexes.CharField语句指定了将模型类中的哪些字段建立索引,而use_template=True说明后续我们将通过一个数据模板文件来指明需要检索的字段

    document=True

    为什么要创建索引:索引就像是一本书的目录,可以为读者提供更快速的导航与查找

    创建模板数据文件

    • 创建数据模板文件

    数据模板文件路径:templates/search/indexes/yourapp/note_text.txt

    放在任何一个你的Django能搜索到的模板文件夹template下面均可,这个文件主要确定要检索的字段,为他们建立索引

    文件名必须为要索引的类名_text.txt,比如这里我们检索的类名是User,那么对应的数据模板文件名为user_text.txt,文件名小写即可

    #template.search.indexes.people.user_text.txt
    {{ object.name }}
    {{ object.account }}
    {{ object.online_time }}
    

    在数据模板文件中使用模板语法,写入需要建立索引的字段,这里我们将模型类中nameaccount以及online_time字段设置索引,当检索时会对这三个字段去做全文检索

    接下来创建一个搜索结果展示页面

    检索结果模板页面

    • 创建检索结果展示页面

    检索结果展示页面,需要在固定的目录路径下进行模板页面的编写

    路径为:templates/search/

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
    </head>
    <body>
    {% if query %}
        <h3>搜索结果如下:</h3>
        {% for result in page.object_list %}
            {{ result.object.name }}
            <br>
            {{ result.object.account }}
            <br>
            {{ result.object.online_time }}
            <br>
        {% empty %}
            <p>没找到</p>
        {% endfor %}
        
        {% if page.has_previous or page.has_next %}
            <div>
                {% if page.has_previous %}
                	<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">
                		上一页
                	</a>
                {% endif %}
    
                {% if page.has_next %}
                	<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">
                		下一页
                	</a>
                {% endif %}
            </div>
        {% endif %}
    {% endif %}
    </body>
    </html>
    

    这个模板页面中已经自带了分页功能,可以按照需求修改

    • 创建检索模板页面内容

    还需要有一个表单,提交检索信息

    <form method='get' action="/search/" >
        <input type="text" name="q">
        <input type="submit" value="查询">
    </form>
    

    这部分检索的模板页面内容可以在你的项目中进行添加,查询方式为get,并且检索输入的表单框name属性必须为q

    中文分词配置

    • 接下来,需要创建有关中文检索的配置文件,这里的配置文件创建为全局

    进入到python的安装目录下,比如我的目录为:C:Python37Libsite-packageshaystackackends

    在该路径下创建名为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()
    

    在这个文件中,定义了一个ChineseAnalyzer的函数,这个函数将替代搜索引擎配置文件中的分词方式

    • 复制引擎文件,修改分词方式为中文

    同样在该文件夹下C:Python37Libsite-packageshaystackackends,复制whoosh_backend.py文件,创建一个新的文件名为whoosh_cn_backend.py,这里复制出一份文件也是为了之后如果不需要使用中文分词,可以直接在settings配置文件中修改引擎为 'ENGINE':'haystack.backends.whoosh_backend.WhooshEngine',

    修改该引擎配置文件中的:analyzer=StemmingAnalyzer()变为analyzer=ChineseAnalyzer()

    并且要记得在头部引入刚才所编写的中文分词文件

    #whoosh_cn_backend.py
    from .ChineseAnalyzer import ChineseAnalyzer
    

    初始化索引

    • 最后,初始化索引数据
    python manage.py rebuild_index
    
  • 相关阅读:
    外键的三种形式
    MySQl创建用户和授权
    Django模板系统
    Django 简介
    jQuery
    JavaScript的BOM和DOM
    JS中的关键字和保留字
    Git 源码管理工具简单入门
    Git使用
    常见的三种SQL分页方式
  • 原文地址:https://www.cnblogs.com/lichaoya/p/13731900.html
Copyright © 2011-2022 走看看