要想在Django中使用Elasticsearch实现全文检索,可以使用 Haystack 来调用 Elasticsearch 搜索引擎
首先需要安装包:
pip install django-haystack
pip install jieba
pip install whoosh
然后是在settings.py中对haystack进行注册:
INSTALLED_APPS = [
、、、
'haystack', #注册 haystack
、、、
]
# 在配置文件中配置Haystack为搜索引擎后端
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'apps.blog.whoosh_cn_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
}
} # 每页显示搜索结果数目为10
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10
# 当添加、修改、删除数据时,自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
在项目的主urls中加入:
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('apps.blog.urls')),
# 记得一定要注意django中的path与re_path
# re_path(r'^search/', include('haystack.urls')),
path('search/', include('haystack.urls')
]
在项目中需要使用到全文检索的子应用中加入search_indexes.py这个文件
from haystack import indexes
# 导入模型类
from .models import Articles
# 修改此处,类名为模型类的名称+Index,比如模型类为Articles,则这里类名为ArticlesIndex
class ArticlesIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
def get_model(self):
# 修改此处,为你自己的model
return Articles
def index_queryset(self, using=None):
return self.get_model().objects.all()
- 索引类ArticlesIndex说明:
- 在ArticlesIndex建立的字段,都可以借助Haystack由Elasticsearch搜索引擎查询。
- 其中text字段我们声明为document=True,表名该字段是主要进行关键字查询的字段。
- text字段的索引值可以由多个数据库模型类字段组成,具体由哪些模型类字段组成,我们用use_template=True表示后续通过模板来指明。
找到你python环境下的安装包haystack所在的位置,打开backend文件夹,复制whoosh_backend.py文件,复制一份,在子应用中创一个名为whoosh_cn_backend.py,然后打开此文件,把下面代码全部复制之后大概在165行附近对复制后的代码的某一行进行进行修改,;
from jieba.analyse import ChineseAnalyzer
#修改前:
schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=StemmingAnalyzer(), field_boost=field_class.boost, sortable=True)
#修改后
schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(), field_boost=field_class.boost, sortable=True)
创建text字段索引值模板文件
在templates目录中创建text字段使用的模板文件
具体在templates/search/indexes/goods/article_text.txt文件中定义(这个文件的命名方式是建立索引所使用的模型类小写_text.txt)
{{ object.title}}
{{ object.body}}
- 模板文件说明:当将关键词通过text参数名传递时
- 此模板指明article的title、body作为text字段的索引值来进行关键字索引查询。
当搜索完成需要将搜索结果需要在templates/search/目录中的search.html文件
进行渲染
Haystack返回的数据包括: - query:搜索关键字
- paginator:分页paginator对象
- page:当前页的page对象(遍历page中的对象,可以得到result对象)
- result.objects: 当前遍历出来的article对象。
{% block article %}
{% if query %}
<div class="row">
<div class="col-md-12">
<div class="alert alert-info">
<span style="font-size: 20px">当前搜索:{{ query }}</span>
<span class="tab5" style="font-size: 20px">共{{paginator.count}}篇</span>
</div>
</div>
</div>
{% endif %}
{% if query and page.object_list %}
{% for article in page.object_list %}
<li >
<div class="lp-content">
<div class="row">
<div class="col-md-12">
<div >
<h4 class="page-header"><a href="/article/{{article.id}}">{{ article.object.title|markdown_content }}</a></h4>
<p>{{ article.object.excerpt|markdown_content }}...</p>
</div>
</div>
</div>
<div class="lp-foot">
<div class="lbfoot-tab">
<span class="tab3 glyphicon glyphicon-tag"><a href="">{{ article.object.category }}</a></span>
<!-- 创建时间 -->
<span class="tab3 glyphicon glyphicon-time"><span style="color: grey;">{{ article.object.created_time }}</span></span>
<!-- 阅读量 -->
<span class="tab3 glyphicon glyphicon-eye-open "><span> {{ article.object.like_num }}</span></span>
<!-- 评论量 -->
<span class="tab3 glyphicon glyphicon-comment "><span> {{ article.object.like_num }}</span></span>
<span class="tab4"><a href="/article/{{article.object.id}}">阅读全文</a></span>
</div>
</div>
</div>
</li>
{% endfor %}
{% else %}
没有找到相关文章!
{% endif %}
{% endblock %}
search.html以及article_text.txt所在的位置如下图所示:
手动的生成索引
python manage.py rebuild_index或者 python manage.py update_index