django-elasticsearch-dsl-drf 搜索服务搭建教学文档

django-elasticsearch-dsl-drf 搜索服务搭建教学

一、整体架构

本搜索服务基于 Django + django-elasticsearch-dsl + django-elasticsearch-dsl-drf 搭建,实现MySQL业务数据与Elasticsearch搜索引擎的联动,提供标准化、可分页、可筛选、可排序的全文搜索API服务。

整体架构流转逻辑:Django模型数据 → ES文档映射 → DRF视图接口 → 前端搜索请求

架构组成说明:

  1. Django Model(SKU):业务数据源,存储商品SKU基础数据

  2. django-elasticsearch-dsl:实现Django与ES的数据映射、索引定义、数据自动同步

  3. django-elasticsearch-dsl-drf:基于DRF封装ES查询能力,提供搜索、过滤、排序、分页接口

  4. Elasticsearch 7.17.x:底层搜索引擎,通过倒排索引实现高效全文检索

  5. documents.py:定义ES索引结构、字段映射、数据过滤规则

  6. DocumentViewSet:核心视图类,搭配各类过滤器实现搜索功能

二、环境依赖安装

搭建前需安装指定版本依赖包,适配ES7.x版本,保证框架兼容性。

Plain 复制代码
pip install django-elasticsearch-dsl==7.3
pip install django-elasticsearch-dsl-drf

三、项目配置(settings.py

在项目配置文件中注册ES相关应用,并配置Elasticsearch服务连接地址。

Plain 复制代码
# settings/dev.py
INSTALLED_APPS = [
    # 原有项目应用
    'django_elasticsearch_dsl',       # ES DSL核心集成
    'django_elasticsearch_dsl_drf',   # ES DSL DRF接口集成
]

# Elasticsearch连接配置
ELASTICSEARCH_DSL = {
    'default': {
        'hosts': 'http://192.168.36.129:9200',  # ES服务地址
    },
}

四、定义ES文档(documents.py

该文件用于绑定Django模型、定义ES索引名称、字段结构、索引配置,同时实现数据过滤和自动同步能力。通过装饰器完成自动注册,无需手动编写信号,即可实现MySQL数据增删改自动同步ES。

Plain 复制代码
# apps/goods/documents.py
from django_elasticsearch_dsl import Document, fields
from django_elasticsearch_dsl.registries import registry
from .models import SKU

@registry.register_document
class SKUDocument(Document):
    """商品SKU搜索文档"""
    # 自定义关联字段
    id = fields.IntegerField(attr='id')
    category_name = fields.TextField(attr='category.name')

    class Index:
        # ES索引名称
        name = 'meiduo_dsl'
        # 索引分片配置
        settings = {
            'number_of_shards': 1,
            'number_of_replicas': 0,
        }

    class Django:
        # 绑定Django业务模型
        model = SKU
        # 自动映射的模型基础字段
        fields = [
            'name',
            'caption',
            'price',
            'sales',
            'stock',
            'is_launched',
        ]

    @classmethod
    def get_queryset(cls):
        """只索引上架商品,过滤无效数据"""
        return SKU.objects.filter(is_launched=True)

五、创建ES数据序列化器(serializers.py

用于序列化ES查询到的文档数据,统一接口返回格式,指定需要对外暴露的字段。

Plain 复制代码
# apps/goods/serializers.py
from django_elasticsearch_dsl_drf.serializers import DocumentSerializer
from .documents import SKUDocument

class SKUDocumentSerializer(DocumentSerializer):
    """ES文档序列化器"""
    class Meta:
        document = SKUDocument
        # 接口返回字段
        fields = [
            'id',
            'name',
            'caption',
            'price',
            'sales',
            'stock',
            'category_name',
            'is_launched',
        ]

六、编写搜索视图(views.py

基于框架提供的DocumentViewSet实现接口能力,配置分页、搜索、过滤、排序后端,实现完整的商品搜索功能。

Plain 复制代码
# apps/goods/views.py
from rest_framework.pagination import PageNumberPagination
from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet
from django_elasticsearch_dsl_drf.filter_backends import (
    FilteringFilterBackend,
    OrderingFilterBackend,
    SearchFilterBackend,
    DefaultOrderingFilterBackend,
)
from .documents import SKUDocument
from .serializers import SKUDocumentSerializer

# 自定义分页类
class StandardResultsSetPagination(PageNumberPagination):
    """标准分页配置"""
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 100

class SKUDocumentViewSet(DocumentViewSet):
    """SKU商品搜索接口视图"""
    document = SKUDocument
    serializer_class = SKUDocumentSerializer
    pagination_class = StandardResultsSetPagination

    # 启用的过滤器后端
    filter_backends = [
        SearchFilterBackend,           # 全文关键词搜索
        FilteringFilterBackend,        # 精确条件过滤
        OrderingFilterBackend,         # 自定义排序
        DefaultOrderingFilterBackend,  # 默认排序兜底
    ]

    # 全文搜索匹配字段
    search_fields = (
        'name',
        'caption',
    )

    # 精确过滤字段映射
    filter_fields = {
        'is_launched': 'is_launched',
    }

    # 支持排序的字段
    ordering_fields = {
        'price': 'price',
        'sales': 'sales',
    }

    # 默认排序规则:销量降序
    ordering = ('-sales',)

七、配置路由(urls.py

通过DRF路由注册视图,生成标准化的搜索接口地址。

Plain 复制代码
# apps/goods/urls.py
from rest_framework.routers import DefaultRouter
from .views import SKUDocumentViewSet

router = DefaultRouter()
# 注册搜索接口路由
router.register('skus/dsl_search', SKUDocumentViewSet, basename='skus_dsl_search')

urlpatterns = router.urls

八、索引创建与数据导入命令

项目配置完成后,需执行命令创建ES索引、导入存量业务数据,接口才可正常使用。

Plain 复制代码
# 进入项目根目录
cd d:\Git01\git-code\meiduo-test01\meiduo_mall

# 1. 创建ES索引结构
python manage.py search_index --create

# 2. 导入模型数据至ES索引
python manage.py search_index --populate

# 3. 重建索引(修改文档字段、索引配置后使用)
python manage.py search_index --rebuild

# 4. 删除索引
python manage.py search_index --delete

九、项目文件结构

Plain 复制代码
meiduo_mall/
├── meiduo_mall/
│   ├── apps/
│   │   └── goods/
│   │       ├── documents.py      # ES索引文档定义
│   │       ├── serializers.py    # ES数据序列化器
│   │       ├── views.py          # 搜索接口视图
│   │       └── urls.py           # 接口路由配置
│   └── settings/
│       └── dev.py                # 项目配置文件(ES配置)
└── requirements.txt              # 项目依赖文件

十、接口查询参数使用说明

1. 全文搜索

通过search参数匹配商品名称、简介关键词

2. 精确过滤

通过is_launched参数过滤上架/下架商品

3. 排序查询

通过ordering参数实现升降序排序

  • 价格升序:/skus/dsl_search/?ordering=price

  • 价格降序:/skus/dsl_search/?ordering=-price

  • 销量降序:/skus/dsl_search/?ordering=-sales

4. 分页查询

通过page、page_size控制分页

  • /skus/dsl_search/?page=1&page_size=10

5. 组合查询

支持搜索、排序、分页多参数组合使用

  • /skus/dsl_search/?search=华为&ordering=-price&page=1&page_size=5

十一、接口响应格式

接口返回标准化分页JSON数据,包含总数量、上下页地址、结果列表。

Plain 复制代码
{
    "count": 8,
    "next": "http://127.0.0.1:8000/skus/dsl_search/?page=2&search=华",
    "previous": null,
    "results": [
        {
            "id": 9,
            "name": "华为 HUAWEI P10 Plus...",
            "caption": "wifi双天线设计!...",
            "price": 3388.0,
            "sales": 21,
            "stock": 6,
            "category_name": "手机",
            "is_launched": true
        }
    ]
}

十二、核心组件功能说明

组件 核心作用
Document 定义ES索引结构、字段映射、索引配置,绑定Django模型
DocumentSerializer 序列化ES文档数据,统一接口返回字段与格式
DocumentViewSet 核心视图,整合所有查询能力,提供搜索API接口
SearchFilterBackend 实现全文关键词搜索功能
FilteringFilterBackend 实现字段精确过滤功能
OrderingFilterBackend 实现自定义字段排序功能
DefaultOrderingFilterBackend 配置接口默认排序规则

十三、数据自动同步机制

通过 @registry.register_document 装饰器自动完成数据同步,无需手动编写信号处理器:

  1. Django中执行 SKU.save()(新增/修改数据)→ ES索引自动更新对应文档

  2. Django中执行 SKU.delete()(删除数据)→ ES索引自动删除对应文档

优势:零代码实现MySQL与Elasticsearch数据实时同步,降低开发成本。

十四、技术对比:Haystack vs dsl-drf

对比项 Haystack dsl-drf
索引定义方式 search_indexes.py + 模板文件 documents.py 配置,更简洁
数据同步 需手动配置信号处理器 装饰器自动同步,无需手动配置
查询方式 HaystackViewSet DocumentViewSet,贴合DRF规范
过滤/排序能力 功能有限 功能强大、配置灵活
ES版本适配 需自定义适配 原生适配ES7.x版本
代码量 冗余代码较多 精简高效

十五、搭建流程总结

  1. 安装依赖:安装dsl核心包与drf适配包

  2. 项目配置:注册应用,配置ES服务连接地址

  3. 定义索引编写documents.py,绑定模型、定义索引结构与数据规则

  4. 编写序列化器:规范ES数据返回格式

  5. 编写视图:配置分页、搜索、过滤、排序后端,实现接口能力

  6. 配置路由:注册视图路由,生成可访问接口

  7. 初始化数据:执行命令创建索引、导入存量数据,完成服务搭建

后续会整理ES数据库相关知识

相关推荐
测试员周周2 小时前
【AI测试系统】第6篇:需求扔进去,3 分钟出测试用例?AI测试系统的 RAG 知识增强实战
人工智能·python·功能测试·测试工具·测试用例
AI玫瑰助手2 小时前
Python入门:Windows/macOS/Linux系统安装Python教程
windows·python·macos
m0_738120722 小时前
网路安全编程——熟悉并使用Scapy简单实现捕捉主流邮箱协议(SMTP、POP3和IMAP) 的身份凭证
网络·python·网络协议·tcp/ip·安全·网络安全
new【一个】对象2 小时前
RAG详解
python·llm·agent·rag
傲笑风2 小时前
jupyter转PDF教程
python·jupyter
测试员周周2 小时前
【AI测试功能2】AI功能测试的“不可确定性“难题与应对思路:从精确断言到统计判定的完整方案
大数据·人工智能·python·功能测试·测试工具·单元测试·测试用例
星光开发者2 小时前
基于springboot电动汽车租赁管理系统-计算机毕设 附源码 11217
javascript·spring boot·mysql·django·php·html5·express
szial2 小时前
uv 实战指南:用一个工具重塑 Python 开发工作流
开发语言·python·uv
Adolf_19932 小时前
Mac 配置Homebrew + Oh My Zsh + npm全局权限问题
大数据·elasticsearch·搜索引擎