zoukankan      html  css  js  c++  java
  • 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:python3Libsite-packageshaystackackends”
      
      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>
      
      
  • 相关阅读:
    javascript数据类型转换
    javascript运算符
    数据类型
    第一个JavaScript代码
    Javascript简介
    z-index
    Java代码优化
    Java中,什么是构造函数?什么是构造函数重载?什么是复制构造函数?
    java中继承条件下构造方法的执行过程
    java中的继承、重载和覆盖是什么意思
  • 原文地址:https://www.cnblogs.com/-min/p/12833239.html
Copyright © 2011-2022 走看看