这些代码的作用是,继承 haystack 默认的 Elasticsearch2SearchBackend 和 Elasticsearch2SearchEngine,覆盖掉它的一些默认行为,这里主要就是让 haystack 在创建索引时,使用指定的 ik 分词器。
由于自定义了搜索引擎,因此在配置文件中将原来指定的 Elasticsearch2SearchEngine 替换为自定义的 Engine:
# 搜索设置 HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'blog.elasticsearch2_ik_backend.Elasticsearch2IkSearchEngine', 'URL': '', 'INDEX_NAME': 'hellodjango_blog_tutorial', }, } HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10 HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'由于修改了索引创建方式,因此需要重建一下索引:python manage.py rebuild_index。然后就可以查看搜索结果了,中文搜索体验是不是好了很多?
防止标题被截断haystack 在展示搜索结果时,默认行为是将第一个出现的关键词前的内容截断,被截掉的部分用省略号代替。对于正文来说,因为内容较多,截断是合理的,但是对于标题这种较短的内容来说,截断就没有必要了。同样的,我们通过继承的方式,替换掉 haystack 的默认行为。我们在 blog/utils.py 中继承 HaystackHighlighter 这个用于高亮搜索关键词的辅助类。
from django.utils.html import strip_tags from haystack.utils import Highlighter as HaystackHighlighter class Highlighter(HaystackHighlighter): """ 自定义关键词高亮器,不截断过短的文本(例如文章标题) """ def highlight(self, text_block): self.text_block = strip_tags(text_block) highlight_locations = self.find_highlightable_words() start_offset, end_offset = self.find_window(highlight_locations) if len(text_block) < self.max_length: start_offset = 0 return self.render_html(highlight_locations, start_offset, end_offset)关键代码是:if len(text_block) < self.max_length:,start_offset 是 haystack 根据关键词算出来第一个关键词在文本中出现的位置。max_length 指定了展示结果的最大长度。我们在代码中做一个判断,如果文本内容 text_block 没有超过允许的最大长度,就将 start_offset 设为 0,这样就从文本的第一个字符开始展示,标题这种短文本就不会被截断了。
然后设置,让 haystack 在高亮文本时,使用我们自定义的辅助类:
HAYSTACK_CUSTOM_HIGHLIGHTER = 'blog.utils.Highlighter'在来看一下搜索效果吧!
线上发布以上步骤都是在本地运行调试的,elasticsearch 服务也是在本地的 Docker 容器中运行,接下来在 production.yml 中加入 elasticsearch 服务,就可以发布线上了,配置内容和 local.yml 是一样的,只是简单修改一下服务名和容器名等命名:
elasticsearch: build: context: . dockerfile: ./compose/production/elasticsearch/Dockerfile image: hellodjango_blog_tutorial_elasticsearch container_name: hellodjango_blog_tutorial_elasticsearch volumes: - esdata:/usr/share/elasticsearch/data ports: - "9200:9200" environment: - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ulimits: memlock: soft: -1 hard: -1 nproc: 65536 nofile: soft: 65536 hard: 65536别忘了修改 settings/production.py,修改线上环境 elasticsearch 服务的连接地址:
HAYSTACK_CONNECTIONS['default']['URL'] = 'http://hellodjango_blog_tutorial_elasticsearch:9200/'这样就可以直接发布线上了!
关注公众号加入交流群