前言
提到django的搜索,使用ORM或原生sql语句一样可以完成,但是在效率上没有haystack+elasticsearch的效率更高
版本
Python3.7
Django==3.2.18
django-haystack==3.1.1
drf-haystack==1.8.11
elasticsearch==1.7.0
djangorestframework==3.13.0
一、先安装elasticsearch服务端
1,在官网上找包 https://www.elastic.co/downloads/past-releases#elasticsearch,版本1.7
点击zip下载
解压下载的文件并进bin目录下找到elasticsearch.bat文件待用
2,在运行elasticsearch.bat文件前需要先安装java环境,这里下载的版本是jdk1.8.0_141
a.进入Java Archive Downloads - Java SE 8官网找到windows版本的jdk-8u141-windows-x64.exe进行下载并安装
b.配置java环境变量,设置变量名为JAVA_HOME,变量值为安装jdk的目录C:\Program Files\Java\jdk1.8.0_141
c.双击用户变量,点击新建,填入%JAVA_HOME%\bin
3,配置完环境变量之后运行bin目录下的elasticsearch.bat文件,在浏览器输入http://localhost:9200有下图输出即安装成功
4,django安装elasticsearch==1.7
pip install -i https://pypi.douban.com/simple elasticsearch==1.7
二、安装drf-haystack和django-haystack并完成相关配置
pip install -i https://pypi.douban.com/simple django-haystack==3.1.1
pip install -i https://pypi.douban.com/simple drf-haystack==1.8.11
1,在INSTALLED_APPS中添加haystack
2,配置haystack的搜索引擎是
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://localhost:9200/', # 此处为elasticsearch运行的服务器ip地址,端口号固定为9200
'INDEX_NAME': 'haystack', # 指定elasticsearch建立的索引库的名称
},
}
# 数据改变时自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
# 指定搜索结果每页的条数 这里设置成了2条
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 2
3,在应用目录下创建search_indexes.py索引文件(文件名固定,不能改)
目录结构:
内容:
from haystack import indexes
from .models import Course
# CourseIndex为模型名+Index
class CourseIndex(indexes.SearchIndex, indexes.Indexable):
"""
Course索引数据模型类
"""
# document=True,表名该字段是主要进行关键字查询的字段, 该字段的索引值可以由多个数据库模型类字段组成(是多个字段,不是多个数据库模型类),具体由哪些模型类字段组成,我们用use_template=True表示后续通过模板来指明,其他字段都是通过model_attr选项指明引用数据库模型类的特定字段。
text = indexes.CharField(document=True, use_template=True)
def get_model(self):
"""返回建立索引的模型类"""
return Course
def index_queryset(self, using=None):
"""返回要建立索引的数据查询集"""
return self.get_model().objects.all()
4,在应用目录下的serializers.py文件里创建序列化器
class CourseModelSerializer(serializers.ModelSerializer):
class Meta:
model = Course
exclude = ('create_time', 'update_time')
from course.search_indexes import CourseIndex
from drf_haystack.serializers import HaystackSerializer
class CourseIndexSerializer(HaystackSerializer):
"""
Course索引结果数据序列化器
"""
object = CourseModelSerializer(read_only=True) # 不要改动object字段
class Meta:
index_classes = [CourseIndex]
fields = ('text', 'object')
5,在与项目manage.py的同目录下新建目录和文件,以如下方式: templates/search/indexes/应用名/模型名小写_text.txt
目录结构如下图:
并在txt文件里定义你想要搜索的字段
{ { object.name }} # 按模型Course的name字段进行搜索
并在settings.py中将templates加入到根目录下
6,在views.py里使用
from course.serializers import CourseIndexSerializer
from drf_haystack.viewsets import HaystackViewSet
# 使用elasticsearch和drf-haystack搜索
class CourseSearchViewSet(HaystackViewSet):
# 索引以 Course表
index_models = [Course]
# 分页
# pagination_class = CoursePagination
# 这里的SPUIndexSerializer 是自定义的序列化类
serializer_class = CourseIndexSerializer
7,在项目根目录的urls.py文件里添加路由
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from course.views import CourseSearchViewSet
router = DefaultRouter()# 使用viewset和routers
router.register(r'course/search', CourseSearchViewSet, basename='search')# 使用viewset和routers
urlpatterns = [
path('qb_admin/', admin.site.urls),
path('', include("course.urls")),
]
urlpatterns += router.urls
8,先手动建立索引
python manage.py rebuild_index
9,运行django项目,在浏览器访问http://127.0.0.1:8000/course/search/?text=Python即可模糊搜索名为Python的课程name字段