pythpn 全文检索的一些使用

一、一些搜素引擎
  • ElasticSearch 企业级搜索引擎最常用,基于lucene的搜索服务器
    • Lucene是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,是一个信息检索程序库
  • whoosh #纯python编写的全文搜索引擎,性能不如其他,但稳定,对于小型网站足够
  • solr
  • Xapian
二、安装
  • pip install django-haystack    
    pip install whoosh #搜素引擎
    pip install jieba  #是一款免费的中文分词
    
    #Haystack 是django的开源全文搜索框架(全文检索不同于特定字段的模糊查询,使用全文检索的效率更高,该框架支持elastisearch,solr,Whoosh
    
  • setiing中 INSTALLED_APPS 添加'haystack'
    
  • 几种不同引擎的配置

    • #Elasticsearch配置
      
      HAYSTACK_CONNECTIONS = {
          'default': {
              'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
              'URL': 'http://127.0.0.1:9200/',
              'INDEX_NAME': 'haystack',
          },
      }
      
    • #Whoosh配置,
      import os
      HAYSTACK_CONNECTIONS = {
          'default': {
              'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
              'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'),
          },
      }
      #PATH是索引文件存放的位置
      # 自动更新索引
      HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
      
    • #Solr配置
      HAYSTACK_CONNECTIONS = {
          'default': {
              'ENGINE': 'haystack.backends.solr_backend.SolrEngine',
              'URL': 'http://127.0.0.1:8983/solr'
              # ...or for multicore...
              # 'URL': 'http://127.0.0.1:8983/solr/mysite',
          },
      }
      
    • #首先安装Xapian后端(http://github.com/notanumber/xapian-haystack/tree/master)
      #PATH是索引文件存放的位置。
      import os
      HAYSTACK_CONNECTIONS = {
          'default': {
              'ENGINE': 'xapian_backend.XapianEngine',
              'PATH': os.path.join(os.path.dirname(__file__), 'xapian_index'),
          },
      }
      
  • 创建索引

    #如果想针对某个app做全文检索,则必须在blog的目录下建立search_indexes.py文件,文件名不能修改。
    from haystack import indexes
    from 模型名Index(indexes.searchIndex,indexes.Indexable):
    	#这里类名必须为要检索的Model+Index
    	text = indexes.CharField(document=True,use_template=True)
    	#创建一个text字段,与模型的字段无关,每个索引里卖弄有且只有一个字段为document =True
    	#其他字段
    	desc = indexes.CharField(model_attr='desc')
    	content = indexes.CharField(model_attr='content')
    	#其他字段只是附属的属性,并不作为检索数据
    	def get_model(self):
    		return 模型名    #重写get_model方法,必须有
        def index_queryset(self,using=None):
        	return self.get_model().objects.all()
    
  • 在templates/search/indexes/应用名称/下创建模型名_text.txt文件

    • #文件中内容为
      {{ object.模型字段名1}}
      {{object.模型字段名2}}
      #这个数据模板的作用是对模型字段1和模型字段2建立索引,当检索的时候会对这三个字段做全文检索
      
  • 设置url

    • 在主路由下添加

    • urlpattern=[
      	path('search/',include(`'haystack.urls'`)),
      	]
      

      haystack.urls源码中也就有一个url指向searchView,可以传递几个关键字参数或者直接重写这个类

  • 定义搜索模板

    搜索模板应该放在templates创建一个search,在search下创建search.html

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <style>
            span.highlighted {
                color: red;
            }
        </style>
    </head>
    <body>
    {% load highlight %}
    {% if query %}
        <h3>搜索结果如下:</h3>
        {% for result in page.object_list %}
    	<a href="/{{ result.object.id }}/">{{ result.object.title }}</a><br/>
        <a href="/{{ result.object.id }}/">{% highlight result.object.title with query max_length 2%}</a><br/>
         <p>{{ result.object.content|safe }}</p>
         <p>{% highlight result.content with query %}</p>
        {% 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 }}">{% endif %}&laquo; 上一页
                {% if page.has_previous %}</a>{% endif %}
                |
                {% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}下一页 &raquo;
                {% if page.has_next %}</a>{% endif %}
            </div>
        {% endif %}
    {% endif %}
    </body>
    </html>
    

    这里的page就是某页的page的对象,page.object_list就是该页的对象列表。

    result.object.字段名result.字段名都能取得数据,暂时没发现不同

  • 生成索引,将数据库中的数据放入索引。

    python manage.py  rebulid_index #会得到有多少模型进行了索引处理的统计
    
  • 使用jieba分词

    #建立ChineseAnalyzer.py文件
    #保存在haystack的安装文件夹下,路径如“D:\python3\Lib\site-packages\haystack\backends”
    
    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
    #注意:复制出来的文件名,末尾会有一个空格,记得要删除这个空格
    from .ChineseAnalyzer import ChineseAnalyzer 
    查找
    analyzer=StemmingAnalyzer()
    改为
    analyzer=ChineseAnalyzer()
    #这里是用的Whoosh搜素引擎,其他也一样。Whoosh的内部是使用正则分词的,我们在这里使用jieba来分词
    #也有Whoosh_backend.py不放在这里嫌麻烦,放外面其他地方。只要把setting中HAYSTACK_CONNECTIONS的ENGINE对应即可
    
  • 模板中使用搜索栏

    <form method='get' action='/search/' target='_blank'
    	<input type='text' name='q'>
    	<input type='submit' value='查询'>
    <form>
    
  • 其他配置,扩展

    如果不满足要求,可以重写SearchView

    from haystack.views import SearchView
    from .models import *
    class MySearchView(SearchView):
    	def extra_context(self):
    		context = super(MySearchView).extra_context()
    		side_list =Topic.objects.filter(字段名='xxx').order_by('xxx')[:5]
    		
    		context['side_list']=side_list
    		return context
    #主路由修改
    path('search',search_views.MySearchView(),name = 'haystack_search')
    

    高亮显示

    //高亮
    {% highlight result.object.字段名 with query}}
    //限制高亮的长度
    {%  highlight result.object.字段名 with query max_length 数字 %}
    
    <style>
    	span.highlighted{
    	color:red;
    	}
    <style>
    
    
posted @ 2019-12-28 16:01  千亿  阅读(109)  评论(0编辑  收藏  举报