> 技术文档 > 【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

在这里插入图片描述


文章目录

  • 前言
  • 一、Elasticsearch
  • 二、Docker 搭建 ES
    • Docker 安装
    • Docker 搭建 ES
  • 三、ES基础语法
    • 创建索引
    • 查看索引
    • 删除索引
    • 添加数据
    • 查询数据
    • 修改数据
    • 删除数据
    • 条件查询
      • 分页查询
      • 排序
    • 多条件查询
      • and
      • or
    • 范围查询
  • 四、ES在项目中的应用示例

前言

    在数据驱动的时代,Elasticsearch以其卓越的全文搜索能力和分布式架构,成为处理海量数据的关键工具。本博客将带您从Elasticsearch的基础概念出发,深入解析其核心——倒排索引,并介绍如何在Docker中轻松部署。我们将详细讲解Elasticsearch的基础语法,确保能够掌握其操作精髓。最后,通过一个实战案例——构建课程搜索与数据同步接口,体验Elasticsearch在实际项目中的强大功能。


一、Elasticsearch

    Elasticsearch(简称ES)是一个基于Lucene构建的开源、分布式、RESTful的搜索和分析引擎。 它以其强大的全文搜索能力、高可用性、可扩展性和易用性而广受欢迎,被广泛应用于各种规模的企业和组织中。

倒排索引

    倒排索引 是 Elasticsearch 及其底层 Lucene 引擎实现快速搜索的关键技术。在传统的数据库中,我们是通过文档(或记录)来查找包含特定关键词的文档列表。而在搜索引擎中,这个过程被逆转了:我们根据关键词来查找包含这些关键词的文档列表。这就是“倒排索引”的由来。
【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

倒排索引是区别于正排索引的概念:

  • 正排索引:是以文档对象的唯一 ID 作为索引,以文档内容作为记录。
  • 倒排索引:Inverted index,指的是将文档内容中的单词作为索引,将包含该词的文档 ID 作为记录。
    【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

倒排索引的结构
    根据倒排索引的概念,我们可以用一个 Map来简单描述这个结构。这个 MapKey 的即是分词后的单词,这里的单词称为 Term,这一系列的 Term 组成了倒排索引的第一个部分 —— Term Dictionary (索引表,可简称为 Dictionary)
    倒排索引的另一部分为 Postings List(记录表),也对应上述 Map 结构的 Value 部分集合。
记录表 由所有的 Term 对应的数据(Postings) 组成,它不仅仅为文档 id 信息,可能包含以下信息:

  • 文档 id(DocId, Document Id),包含单词的所有文档唯一 id,用于去正排索引中查询原始数据。
  • 词频(TF,Term Frequency),记录 Term 在每篇文档中出现的次数,用于后续相关性算分。
  • 位置(Position),记录 Term 在每篇文档中的分词位置(多个),用于做词语搜索(Phrase Query)。
  • 偏移(Offset),记录 Term 在每篇文档的开始和结束位置,用于高亮显示等。

二、Docker 搭建 ES

Docker 安装

升级所有包同时也升级软件和系统内核:

  • yum -y update

只升级所有包,不升级软件和系统内核:

  • yum -y upgrade

删除自带的docker

  • yum remove docker docker-common docker-selinux docker-engine

安装需要的软件包, yum-util 提供yum-config-manager功能,另两个是devicemapper驱动依赖

  • yum install -y yum-utils device-mapper-persistent-data lvm2

设置一个yum源,下面两个都可用,选择一个

  • yum-config-manager --add-repo http://download.docker.com/linux/centos/docker-ce.repo(中央仓库)
  • yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo(阿里仓库)

查看docker可用版本

  • yum list docker-ce --showduplicates | sort -r

安装docker

  • yum -y install docker-ce-18.03.1.ce

设置开机启动

  • systemctl start docker
  • systemctl enable docker

Docker 搭建 ES

docker 拉取 elasticsearch镜像

  • docker pull elasticsearch:7.7.0
  • docker pull docker.elastic.co/elasticsearch/elasticsearch:7.7.0

docker 运行 elasticsearch

  • docker run --name elasticsearch -d -e ES_JAVA_OPTS=\"-Xms512m -Xmx512m\" -e \"discovery.type=single-node\" -p 9200:9200 -p 9300:9300 elasticsearch:7.7.0

三、ES基础语法

创建索引

发送put请求: http://localhost:9200/shopping
【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

查看索引

发送get请求: http://localhost:9200/shopping
【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

查看所有索引 http://localhost:9200/_cat/indices?v
【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

删除索引

发送delete请求 http://localhost:9200/shopping
【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

添加数据

发送post请求 http://localhost:9200/shopping/_doc

请求体Body:{\"name\":\"张三\",\"age\":10,\"category\":1,\"status\":1,\"online\":2}

【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

幂等性操作

  • 添加时添加id ,http://localhost:9200/shopping/_doc/1001
    【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

查询数据

发送get请求

  • 查询单个 http://localhost:9200/shopping/_doc/1002
    【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

  • 查询全部 http://localhost:9200/shopping/_search
    【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

修改数据

完全覆盖

  • 发送put请求 http://localhost:9200/shopping/_doc/1001
    【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

修改某个属性

  • 发送post请求 http://localhost:9200/shopping/_update/1001
发送post请求 http://localhost:9200/shopping/_update/1001{ \"doc\": { \"name\": \"张三22\" } }

【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

删除数据

完全覆盖

  • 发送delete请求 http://localhost:9200/shopping/_doc/1001
    【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

条件查询

get http://localhost:9200/shopping/_search{\"query\":{\"match\":{\"category\":1}}}

查询category为1的数据:
【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

查询所有数据{\"query\":{\"match_all\":{}}}

查询所有数据:
【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

分页查询

{\"query\":{\"match_all\":{}},\"from\":0,\"size\":2}

【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

指定name姓名字段{\"query\":{\"match_all\":{}},\"from\":0,\"size\":2,\"_source\":[\"name\"]}

指定name姓名字段:
【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

排序

{\"query\":{\"match_all\":{}},\"from\":0,\"size\":2,\"_source\":[\"name\",\"age\"],\"sort\":{\"id\":{\"order\":\"desc\"}}}

【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

多条件查询

and

{\"query\":{\"bool\":{\"must\":[{\"match\":{\"age\":10}},{\"match\":{\"name\":\"张三\"}}]}},\"from\":0,\"size\":2,\"_source\":[\"name\",\"age\"],\"sort\":{\"age\":{\"order\":\"desc\"}}}select * from users where age=10 and name=\"张三\"

select * from users where age=10 and name=“张三”
【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

or

{\"query\":{\"bool\":{\"should\":[{\"match\":{\"age\":10}},{\"match\":{\"name\":\"张三\"}}]}},\"from\":0,\"size\":2,\"_source\":[\"name\",\"age\"],\"sort\":{\"age\":{\"order\":\"desc\"}}}select * from users where age=10 or name=\"张三\"

select * from users where age=10 or name=“张三”
【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

范围查询

es支持常用的语法,通过

  • from size进行分页查询,
  • match条件查询,
  • _source指定返回字段,
  • sort排序,
  • range进行区间查询,
  • must并且查询,
  • should进行或查询
{\"query\":{\"bool\":{\"should\":[{\"match\":{\"age\":10}},{\"match\":{\"name\":\"张三\"}}],\"filter\":{\"range\":{\"age\":{\"gt\":3}}}}},\"from\":0,\"size\":2,\"_source\":[\"name\",\"age\"],\"sort\":{\"age\":{\"order\":\"desc\"}}}

【Django+Vue3 线上教育平台项目实战】Elasticsearch实战指南:从基础到构建课程搜索与数据同步接口_elasticsearch django 课程

四、ES在项目中的应用示例

使用es查询课程信息:

  • 1.实例化Elasticsearch类
  • 2.es.index创建索引,把记录添加到es中
  • 3.先mysql中的数据加载到es中,第一次全量式同步,后面增量式同步
  • 4.用es._search从查询数据

    下面代码示例展示了如何使用Django REST framework的APIView以及Elasticsearch客户端来实现一个简单的课程搜索和数据同步接口。

#course/views.py#demo:esfrom elasticsearch import Elasticsearches = Elasticsearch(\"http://localhost:9200/\")class CourseSearchEs(APIView):#对课程构建索引 def get(self, request): dsl = { \"query\":{ \"match\":{} }, \'from\':0, \'size\':2, \'_source\':[\'id\',\'name\',\'sales\'] } res = es.search(index=\"ccourse\", body=dsl) data = res[\'hits\'][\'hits\'] clist = [] for i in data: clist.append(i[\'_source\']) return Response({\"code\": \"200\", \"data\": clist}) def post(self, request): # 查询课程中所有数据 course = CourseModel.objects.all() # 数据同步---全量式同步 for c in course: es.index(index=\'ccourse\',body={ \'id\': c.id, \'table_name\':\'course\', \'name\':c.name, \'sales\':c.sales, \'describe\':c.describe, }) r.setex_str(\'id\',60*60,c.id) #会覆盖,只存最后一次id(最大id) return Response({\"code\": \"200\"})
# base/tasks.py@shared_taskdef syn_mysql_es(): es = Elasticsearch(\"http://120.46.9.231:9200/\") # 查询上次最终更新课程id后的所有数据 cid = r.get_str(\"id\") print(cid) course = CourseModel.objects.filter(id__gt=cid) # 数据同步---增量式同步(定时同步数据) for c in course: es.index(index=\'ccourse\', body={ \'id\': c.id, \'table_name\': \'course\', \'name\': c.name, \'sales\': c.sales, \'describe\': c.describe, }) r.setex_str(\'id\', 60 * 60, c.id) print(\"mysql_es_数据同步完成...\")

在这里插入图片描述