Elasticsearch文档基础操作(增删改,搜索)
环境准备
- Elasticsearch 服务(单机或集群)
- Kibana 服务
如果对ES不了解或没有上述环境,可以看下我之前的博客。
Elasticsearch查看集群信息,设置ES密码,Kibana部署
进入 Kibana 开发工具
增删改
# 增加文档,也可以不指定id,由ES提供 例:POST /user/_doc/
POST /user/_doc/001
{
"name": "Tim John",
"tag": "男,华裔,白种人,帅哥,热心肠",
"age": "18"
}
# 批量写入文档
POST /_bulk
{"index":{"_index":"user","_id":"002"}}
{"name":"李华","tag":"黄种人,高中未毕业,天天写英语作文","age":"25"}
{"index":{"_index":"user"}}
{"name":"张三","tag":"浙大硕士,黄种人","age":"25"}
# 查询文档信息
GET /user/_doc/002
# 修改文档,修改文档后_version 版本号会+1
# 重新执行插入 的语句,会覆盖之前的数据,每次覆盖版本号都会+1
POST /user/_doc/001
{
"name": "Tim John",
"tag": "男,华裔,白种人,帅哥,热心肠",
"age": "18"
}
# 修改文档,只有真正修改内容,版本号才会+1
POST /user/_update/005
{
"doc": {
"name": "Tim John",
"tag": "女,华裔,白种人,帅哥,热心肠",
"age": "18"
},
// 不存在,则插入数据
"upsert": {
"name": "Tim John",
"tag": "女,华裔,白种人,帅哥,热心肠",
"age": "18"
}
}
# 批量更新
POST /_bulk
{"update":{"_index":"user","_id":"002"}}
{"doc":{"name":"李华","tag":"黄种人,高中未毕业,天天写英语作文","age":"25"}}
{"update":{"_index":"user","_id":"003"}}
{"doc":{"name":"张三","tag":"浙大硕士,黄种人","age":"25"}}
# 根据条件更新
# 将张三 名字修改为李四
POST /user/_update_by_query
{
"query": {
"term": {
"name.keyword": {
"value": "张三"
}
}
},
"script": {
//painless 是一种安全的脚本语言
//ctx(context) 是 painless 脚本上的一个引用 这里指向正在处理的文档
"source": "ctx._source['name']='李四'",
"lang": "painless"
}
}
# 删除文档
# 删除单条文档
DELETE /user/_doc/003
# 批量删除文档
POST /_bulk
{"delete":{"_index":"user","_id":"001"}}
{"delete":{"_index":"user","_id":"002"}}
# 根据条件删除文档
# 删除 叫李四的文档
POST /user/_delete_by_query
{
"query": {
"term": {
"name.keyword": {
"value": "李四"
}
}
}
}
搜索
数据准备
创建课程courses 索引,并插入 15条数据
PUT /courses
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
},
"mappings": {
"properties": {
"course_name": {
"type": "text"
},
"course_desc": {
"type": "text"
},
"course_duration": {
"type": "integer"
},
"teacher": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"category": {
"type": "keyword"
},
"create_time": {
"type": "date",
"format": [
"yyyy-MM-dd HH:mm:ss"
]
}
}
}
}
POST /courses/_bulk
{ "index" : { "_id" : "1" } }
{ "course_name" : "Python编程入门", "course_desc" : "适合没有编程经验的学员,从基础开始学Python", "course_duration" : 30, "teacher" : "张教授", "category" : "编程语言", "create_time": "2022-02-22 12:00:00" }
{ "index" : { "_id" : "2" } }
{ "course_name" : "数据科学与分析", "course_desc" : "涵盖数据分析、统计学及机器学习基础", "course_duration" : 50, "teacher" : "李博士", "category" : "数据分析" , "create_time": "2023-02-22 13:00:20"}
{ "index" : { "_id" : "3" } }
{ "course_name" : "Web前端开发", "course_desc" : "HTML, CSS, JavaScript及React框架的学习", "course_duration" : 45, "teacher" : "王工", "category" : "Web开发" , "create_time": "2024-02-22 08:12:00"}
{ "index" : { "_id" : "4" } }
{ "course_name" : "Java编程进阶", "course_desc" : "面向对象编程,设计模式及高级特性", "course_duration" : 60, "teacher" : "赵老师", "category" : "编程语言" , "create_time": "2022-02-22 15:00:00"}
{ "index" : { "_id" : "5" } }
{ "course_name" : "移动应用开发", "course_desc" : "iOS和Android平台的应用开发课程", "course_duration" : 70, "teacher" : "刘导师", "category" : "移动开发" , "create_time": "2022-02-22 12:02:01"}
{ "index" : { "_id" : "6" } }
{ "course_name" : "数据库管理与SQL", "course_desc" : "关系型数据库原理,SQL查询优化与管理", "course_duration" : 40, "teacher" : "陈工程师", "category" : "数据库", "create_time": "2023-03-15 14:00:00"}
{ "index" : { "_id" : "7" } }
{ "course_name" : "Python数据分析实战", "course_desc" : "使用Pandas、NumPy进行数据清洗与分析", "course_duration" : 55, "teacher" : "周数据分析师", "category" : "数据分析", "create_time": "2023-04-20 10:30:00"}
{ "index" : { "_id" : "8" } }
{ "course_name" : "全栈开发工程师路径", "course_desc" : "从前端到后端,涵盖Node.js与Vue框架", "course_duration" : 65, "teacher" : "吴全栈开发者", "category" : "Web开发", "create_time": "2024-05-12 16:45:00"}
{ "index" : { "_id" : "9" } }
{ "course_name" : "C++高级编程", "course_desc" : "深入理解C++特性,模板元编程及STL库", "course_duration" : 48, "teacher" : "郑教授", "category" : "编程语言", "create_time": "2023-06-22 09:00:00"}
{ "index" : { "_id" : "10" } }
{ "course_name" : "Android应用开发深化", "course_desc" : "Kotlin语言,Android Jetpack组件与架构模式", "course_duration" : 50, "teacher" : "孙开发者", "category" : "移动开发", "create_time": "2024-07-10 11:30:00"}
{ "index" : { "_id" : "11" } }
{ "course_name" : "云计算与AWS服务", "course_desc" : "云基础概念,亚马逊云服务实战部署", "course_duration" : 38, "teacher" : "钱云架构师", "category" : "云计算", "create_time": "2025-02-25 13:15:00"}
{ "index" : { "_id" : "12" } }
{ "course_name" : "网络安全基础", "course_desc" : "网络协议,加密技术与安全防护措施", "course_duration" : 42, "teacher" : "朱安全专家", "category" : "网络安全", "create_time": "2025-03-18 14:40:00"}
{ "index" : { "_id" : "13" } }
{ "course_name" : "R语言在统计学中的应用", "course_desc" : "R语言基础,统计模型建立与数据可视化", "course_duration" : 35, "teacher" : "何统计学家", "category" : "编程语言", "create_time": "2025-04-12 15:20:00"}
{ "index" : { "_id" : "14" } }
{ "course_name" : "Django Web框架精通", "course_desc" : "Python Django实战,构建RESTful API", "course_duration" : 50, "teacher" : "杨框架专家", "category" : "Web开发", "create_time": "2025-05-20 10:00:00"}
{ "index" : { "_id" : "15" } }
{ "course_name" : "区块链技术与应用", "course_desc" : "去中心化原理,智能合约与以太坊开发", "course_duration" : 45, "teacher" : "罗区块链工程师", "category" : "新兴技术", "create_time": "2025-06-10 12:30:00"}
搜索基础
指定返回字段
"_source": ["course_name","teacher"]
指定返回 couse_name 和 teacher 字段
相当于 SQL 中的 select course_name, teacher
GET /courses/_search
{
"_source": ["course_name","teacher"],
"query": {
"term": {
"category": {
"value": "编程语言"
}
}
}
}
结果统计
结果统计
相当于 select count(*)
GET /courses/_count
{
"query": {
"term": {
"category": {
"value": "编程语言"
}
}
}
}
分页查询
ES默认只返回前10条数据(hits 里的内容默认只有10条)
GET /courses/_search
{
"from": 5,
"size": 5
}
默认情况下,用户最多可以获取前10000 个数据
与关系型数据库一样,ES 也不适合做深分页
ES更适合的场景是对数据进行搜索,而不是进行大规模的数据遍历
匹配搜索
针对不同的数据类型,ES提供了很多搜索匹配功能
查全部
GET /courses/_search
GET /courses/_search
{
"query": {
"match_all": {
"boost": 2 //设定返回文档的分值,默认是1.0
}
}
}
注意:默认 hits中只返回10条数据
term 完全匹配
相当于 RDB 的等值匹配(where a = 1
)
支持 term 完全匹配的字段类型 有 : keyword ,数值类型,布尔类型,日期类型,数组类型
# 查询 分类为 编程语言的课程
GET /courses/_search
{
"query": {
"term": {
"category": {
"value": "编程语言"
}
}
}
}
text 类型不支持 term 查询 , 下面的请求结果为空
GET /courses/_search
{
"query": {
"term": {
"teacher": {
"value": "郑教授"
}
}
}
}
对于 date日期的查询 ,需要与定义的日期格式一致,否则查询失败报错
GET /courses/_search
{
"query": {
"term": {
"create_time": {
"value": "2024-02-22 08:12:00"
}
}
}
}
若格式不匹配 提示错误信息,如图
terms 完全匹配
用于查询一个值或多个值是否完全匹配
相当于 RDB 中的 或 (where a = 1 or a = 2
)
# 查询 分类为 编程语言 或 云计算的课程
GET /courses/_search
{
"query": {
"terms": {
"category": ["编程语言","云计算"]
}
}
}
range 范围匹配
一般用于 数值型 或者 日期类型 的范围查询
比较关键字
gt: 大于
lt: 小于
gte:大于等于
lte: 小于等于
# 查询时长在[30,40]之间的数据
GET /courses/_search
{
"query": {
"range": {
"course_duration": {
"gte": 30,
"lte": 40
}
}
}
}
exists 存在查询
用于查询某个字段不为空 的文档
为空的情况
- 非数组类型,值为null
- 数组类型 ,空数组[] 或 [null]
# 查询存在分类信息的文档
GET /courses/_search
{
"query": {
"exists": {
"field": "category"
}
}
}
全文搜索
类似 RDB 中的 模糊查询(where a like "%aaa%"
)
全文搜索 就是 针对 text 类型的数据搜索。是部分匹配。
不同于结构化查询,全文搜索首先对查询词进行分析,然后根据查询词的分词结果构建查询。
match 分词匹配
match查询是全文搜索的主要代表。对于最基本的match搜索来说,只要分词中的一个或者多个在文档中存在即可。
ES 默认的标准分词器,不支持中文分词,对于中文 将按字进行切分。
若需要切分中文,需要自行安装中文分词器,如IK分词器等。
例如搜索 “框架学习”。
查询词会根据分词器 将 ”框架学习“ 切分为“框” “架” “学” “习”,因此,只要文档中包含这4个字中的任何一个字,都会被搜索到。
并根据匹配度进行打分,并按照分数倒叙排序返回结果
默认 匹配分词是或的关系,即 框架学习 四个字含有任意一个都可以
GET /courses/_search
{
"query": {
"match": {
"course_desc": "框架学习"
}
}
}
# 如果想精准搜索 包含框架学习 四个字的 结果可以指定操作符为and
GET /courses/_search
{
"query": {
"match": {
"course_desc": {
"query": "框架学习",
"operator": "and"
}
}
}
}
# 也可以指定最小匹配度,例如:匹配度到达50% 即含有任意两个字的结果
GET /courses/_search
{
"query": {
"match": {
"course_desc": {
"query": "框架学习",
"operator": "or",
"minimum_should_match": "50%"
}
}
}
}
multi_match 多值匹配
等价于 使用bool 查询 封装多个 match
bool查询 属于复合查询,在下面会解释
# 查询课程名称 或者 课程描述包含 框架 的文档
GET /courses/_search
{
"query": {
"multi_match": {
"query": "框架",
"fields": ["course_desc","course_name"]
}
}
}
match_phrase 短语匹配
match_phrase用于匹配短语,与match查询不同的是,match_phrase用于搜索确切的短语或邻近的词语。
例如 查询 “框架学习”,希望查询的结果 必须包含 “框架学习” 这个短语
GET /courses/_search
{
"query": {
"match_phrase": {
"course_desc": {
"query": "框架学习"
}
}
}
}
如果允许短语之间 有 距离 可以使用 slop参数指定 距离阈值
# 查询 "框架学习" 短语,允许词语之间的距离为1
# 例如 "框架的学习"
GET /courses/_search
{
"query": {
"match_phrase": {
"course_desc": {
"query": "框架学习",
"slop": 1
}
}
}
}
复合查询
Bool查询
bool 查询是 ES 中使用最为广泛的复合查询,可以组合多个查询条件和过滤器,支持must、should、must_not 等子句,可以实现AND、OR、NOT 等逻辑关系操作。
# 查询 24年之后 分类为 编程语言 ,
# 讲师为何统计学家 或者 李博士 ,
# 课程描述不含JAVA的课程
GET /courses/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"create_time": {
"gte": "2024-01-01 00:00:00"
}
}
}
],
"should": [
{
"term": {
"teacher.keyword": "何统计学家"
}
},
{
"term": {
"teacher.keyword": "李博士"
}
}
],
"must_not": [
{
"match": {
"course_desc": "JAVA"
}
}
],
"filter": {
"term": {
"category": "编程语言"
}
}
}
}
}
filter查询即过滤查询,该查询是布尔查询里非常独特的一种查询。
其他布尔查询关注的是查询条件和文档的匹配程度,并按照匹配程度进行打分;
而 fiter查询关注的是查询条件和文档是否匹配,不进行相关的打分计算,但是会对部分匹配结果进行缓存。