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>
      
      
  • 相关阅读:
    (Java) LeetCode 44. Wildcard Matching —— 通配符匹配
    (Java) LeetCode 30. Substring with Concatenation of All Words —— 与所有单词相关联的字串
    (Java) LeetCode 515. Find Largest Value in Each Tree Row —— 在每个树行中找最大值
    (Java) LeetCode 433. Minimum Genetic Mutation —— 最小基因变化
    (Java) LeetCode 413. Arithmetic Slices —— 等差数列划分
    (Java) LeetCode 289. Game of Life —— 生命游戏
    (Java) LeetCode 337. House Robber III —— 打家劫舍 III
    (Java) LeetCode 213. House Robber II —— 打家劫舍 II
    (Java) LeetCode 198. House Robber —— 打家劫舍
    (Java) LeetCode 152. Maximum Product Subarray —— 乘积最大子序列
  • 原文地址:https://www.cnblogs.com/-min/p/12833239.html
Copyright © 2011-2022 走看看