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
    
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    现在使用控件, 更喜欢继承(覆盖控件已有的函数,很奇怪的一种使用方式)
    Controls 属性与继承 TShape 类的小练习(使用TShape可以解决很多图形问题)
    QT创建窗口程序、消息循环和WinMain函数(为主线程建立了一个QEventLoop,并执行exec函数)
  • 原文地址:https://www.cnblogs.com/lichaoya/p/13731900.html
Copyright © 2011-2022 走看看