Django项目使用Elasticsearch全文搜索引擎实现搜索优化
简介
由于项目需要用到模糊搜索, Mysql模糊查询正常情况下在数据量小的时候,速度还是可以的,数据表数据量大的时候就会查询时效率低下, 对此, 使用全文搜索引擎就是一个很好的解决方法.
Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。
在 Django 项目中使用Elasticsearch有很多现成的库, 比如elasticsearch,django-elasticsearch-dsl, django-haystack , drf_haystack 等。
Haystack 是在 Django 中对接搜索引擎的框架,搭建了用户和搜索引擎之间的沟通桥梁。
我们在 Django 中可以通过使用 Haystack 来调用 Elasticsearch 搜索引擎。
Haystack 可以在不修改代码的情况下使用不同的搜索后端(比如 Elasticsearch、Whoosh、Solr等等)。
需要注意的是Haystack只支持es6以下的版本
准备
下载elasticsearch 2.4.6版本, 建议使用docker方式安装, 注意版本号
下载kibana 4.6.4版本,用于管理
下载对应版本的中文分词插件elasticsearch-analysis-ik-1.10.6.zip, 在es安装好下载的插件
下载地址
https://www.elastic.co/cn/elasticsearch/
https://www.elastic.co/cn/downloads/kibana
https://github.com/medcl/elasticsearch-analysis-ik/releases?page=13
docker镜像市场: http://hub.daocloud.io/
Docker安装
在服务器上新建配置文件docker-compose.yml
version: "2"
services:
elasticsearch:
image: daocloud.io/library/elasticsearch:2.6.4
restart: always
container_name: elasticserach
ports:
- "9200:9200"
kibana:
image: daocloud.io/library/kibana:4.6.4
restart: always
container_name: kibana
ports:
- "5601:5601"
environment:
- elasticsearch_url=http://127.0.0.1:9200
depends_on:
- elasticsearch
输入命令安装
docker-compose up -d
安装分词插件
docker ps # 查看当前运行进程
docker exec -it es镜像id bash
cd bin
./elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v2.6.4/elasticsearch-analysis-ik-1.10.6.zip
重启es
docker restart es镜像id
安装好Python需要的库
pip install django-haystack
pip install elasticsearch==2.4.1 # 注意版本2.4.1
pip install drf_haystack
drf_haystack 文档
https://drf-haystack.readthedocs.io/en/latest/index.html
示例
1.配置
再设置里配置添加app
INSTALLED_APPS = [
'haystack',
...
]
配置链接
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/', # 此处为elasticsearch运行的服务器ip地址和端口
'INDEX_NAME': 'gameprop', # 指定elasticserach建立的索引库名称
},
}
# 搜索结果每页显示数量
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 5
# 实时更新index
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
2.创建haystack数据模型
在app名/模块名
目录下创建search_indexes.py
文件,注意文件名必须使用search_indexes.py
,代码如下:
from haystack import indexes
from Headlines.models import Article
class ArticleIndex(indexes.SearchIndex, indexes.Indexable):
"""文章索引模型类"""
text = indexes.CharField(document=True, use_template=True)
id = indexes.IntegerField(model_attr='id')
createtime = indexes.DateTimeField(model_attr='createtime')
content = indexes.CharField(model_attr='content')
title = indexes.CharField(model_attr='title')
def get_model(self):
"""返回建立索引的模型类"""
return Article
def index_queryset(self, using=None):
"""返回要建立索引的数据查询集"""
return self.get_model().objects.all()
3.创建 text 字段索引值模板文件
创建 text 字段索引值模板文件templates/search/indexes/APP名/模块名_text.txt
{{ object.id }}
{{ object.title }}
{{ object.channel }}
{{ object.labels }}
{{ object.content }}
4.手动生成初始索引
在命令行中添加如下命令, 来手动生成索引表:
python manage.py rebuild_index
5.编辑视图文件views.py
from drf_haystack.viewsets import HaystackViewSet
# 搜索文章
class SearchArticleViewSet(HaystackViewSet):
# GET /Headlines/search/?text=<搜索关键字>
# 这里可以写多个模型,相应的:serializer里也可以写多个index_classes
index_models = [Article]
serializer_class = SearchArticleIndexSerializer
6.编辑序列化器serializers.py
from drf_haystack import serializers as HSER
# 搜索文章
class SearchArticleIndexSerializer(HSER.HaystackSerializer):
class Meta:
index_classes = [ArticleIndex] # 索引类的名称,可以有多个
fields = ('text', 'content', 'id', 'title', 'createtime')
7.编辑路由urls.py
# 搜索文章路由
from rest_framework.routers import DefaultRouter
from Headlines.views import SearchArticleViewSet
router = DefaultRouter()
router.register(r'Headlines/search', SearchArticleViewSet, base_name='search')
urlpatterns += router.urls
新版本的不行嘛
es多个版本都有些区别, 不兼容, 好像只能支持到5.x