drf-haystack + elasticsearch实现搜索功能

前言

提到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字段

猜你喜欢

转载自blog.csdn.net/qq_37140721/article/details/129880925
今日推荐