Django Haystack 全文检索与关键词高亮 (3)

haystack_search 视图函数会将搜索结果传递给模板 search/search.html,因此创建这个模板文件,对搜索结果进行渲染:

templates/search/search.html {% extends 'base.html' %} {% load highlight %} {% block main %} {% if query %} {% for result in page.object_list %} <article> <header> <h1> <a href="{{ result.object.get_absolute_url }}">{% highlight result.object.title with query %}</a> </h1> <div> <span> <a href="{% url 'blog:category' result.object.category.pk %}"> {{ result.object.category.name }}</a></span> <span><a href="#"> <time datetime="{{ result.object.created_time }}"> {{ result.object.created_time }}</time></a></span> <span><a href="#">{{ result.object.author }}</a></span> <span> <a href="{{ result.object.get_absolute_url }}#comment-area"> {{ result.object.comment_set.count }} 评论</a></span> <span><a href="{{ result.object.get_absolute_url }}">{{ result.object.views }} 阅读</a></span> </div> </header> <div> <p>{% highlight result.object.body with query %}</p> <div> <a href="{{ result.object.get_absolute_url }}">继续阅读 <span>→</span></a> </div> </div> </article> {% empty %} <div>没有搜索到你想要的结果!</div> {% endfor %} {% if page.has_previous or page.has_next %} <div> {% if page.has_previous %} <a href="?q=http://www.likecs.com/{{ query }}&amp;page=http://www.likecs.com/{{ page.previous_page_number }}">{% endif %}&laquo; Previous {% if page.has_previous %}</a>{% endif %} <span>|</span> {% if page.has_next %}<a href="?q=http://www.likecs.com/{{ query }}&amp;page=http://www.likecs.com/{{ page.next_page_number }}">{% endif %}Next &raquo;{% if page.has_next %}</a>{% endif %} </div> {% endif %} {% else %} 请输入搜索关键词,例如 django {% endif %} {% endblock main %}

这个模板基本和 blog/index.html 一样,只是由于 haystack 对搜索结果做了分页,传给模板的变量是一个 page 对象,所以我们从 page 中取出这一页对应的搜索结果,然后对其循环显示,即 {% for result in page.object_list %}。另外要取得 Post(文章)以显示文章的数据如标题、正文,需要从 result 的 object 属性中获取。query 变量的值即为用户搜索的关键词。

高亮关键词

注意到百度的搜索结果页面,含有用户搜索的关键词的地方都是被标红的,在 django haystack 中实现这个效果也非常简单,只需要使用 {% highlight %} 模板标签即可,其用法如下:

# 使用默认值 {% highlight result.summary with query %} # 这里我们为 {{ result.summary }} 里所有的 {{ query }} 指定了一个<div></div>标签,并且将class设置为highlight_me_please,这样就可以自己通过CSS为{{ query }}添加高亮效果了,怎么样,是不是很科学呢 {% highlight result.summary with query html_tag "div" css_class "highlight_me_please" %} # 可以 max_length 限制最终{{ result.summary }} 被高亮处理后的长度 {% highlight result.summary with query max_length 40 %}

在博客文章搜索页中我们对 title 和 body 做了高亮处理:{% highlight result.object.title with query %},{% highlight result.object.body with query %}。高亮处理的原理其实就是给文本中的关键字包上一个 span 标签并且为其添加 highlighted 样式(当然你也可以修改这个默认行为,具体参见上边给出的用法)。因此我们还要给 highlighted 类指定样式,在 base.html 中添加即可:

base.html <head> <title>Black &amp; White</title> ... <style> /* 搜索关键词高亮 */ span.highlighted { color: red; } </style> ... </head> 建立索引文件

最后一步就是建立索引文件了,运行命令 :

$ docker exec -it hellodjango_blog_tutorial_local python manage.py rebuild_index

就可以建立索引文件了。一切就绪后,就可以尝试搜索了。但是体验下来会发现搜索的结果并不是很友好,很多关键词文章中命名存在但搜索结果中却没有显示,原因是 haystack 专门为英文搜索设计,如果使用其默认的搜索引擎分词器,中文搜索的结果就不是很理想,接下来我们来将它默认的分词器设置为中文分词器。

修改搜索引擎为中文分词

还记得文章开头编排 elasticsearch 的 Docker 镜像时,我们将一个 elasticsearch 的中文分词插件复制到了 elasticsearch 的插件目录,接下来要做的,就是让 haystack 在创建索引时,使用指定的插件来对进行分词并创建索引,具体做法是,首先在 blog 应用下创建一个 elasticsearch2_ik_backend.py,代码如下:

from haystack.backends.elasticsearch2_backend import Elasticsearch2SearchBackend, Elasticsearch2SearchEngine DEFAULT_FIELD_MAPPING = {'type': 'string', "analyzer": "ik_max_word", "search_analyzer": "ik_smart"} class Elasticsearch2IkSearchBackend(Elasticsearch2SearchBackend): def __init__(self, *args, **kwargs): self.DEFAULT_SETTINGS['settings']['analysis']['analyzer']['ik_analyzer'] = { "type": "custom", "tokenizer": "ik_max_word", } super(Elasticsearch2IkSearchBackend, self).__init__(*args, **kwargs) class Elasticsearch2IkSearchEngine(Elasticsearch2SearchEngine): backend = Elasticsearch2IkSearchBackend

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwsjwg.html