1.基本概念
1.Index(索引)相当于数据库 动词,相当于 MySQL 中的 insert;
名词,相当于 MySQL 中的 Database
2.Type(类型) 相当于表(7版本已经不建议使用) 在 Index(索引)中,可以定义一个或多个类型。
类似于 MySQL 中的 Table;每一种类型的数据放在一起;
3.Document(文档) 相当于表中的数据 保存在某个索引(Index)下,某种类型(Type)的一个数据(Document),文档是 JSON 格 式的,Document 就像是 MySQL 中的某个 Table 里面的内容;
文章图片
4.倒排索引
文章图片
es在保存记录时,会同事创建一张表维护倒排索引。把存入的记录进行分词。
如图,在保存红海行动这条记录时,会生成红海和行动两个词,表中红海和行动的记录这一列就有1号记录,添加第二条探索红海行动这条记录时,红海和行动的记录这一列也有了2号记录,探索这条数据的记录这一列也有了2号记录。
检索时,比如输入红海特工行动,查找红海 特工 行动 这三条数据的记录这一列都有那条记录,因为红海这个词在1-5号记录都有,所以数据都会被查出来,看哪个最多得出相关性得分进行排序,此时 1号和2号记录都有 红海和行动,5号记录有红海和特工,所以他们相关性得分会比较高,1号记录时两个词占了两个词,2号记录是三个词占了两个词,5号记录是4歌词占了两个词,所以1号记录的相关性得分最高,排在最前面。
2.初步检索
1._cat GET /_cat/nodes:查看所有节点
GET /_cat/health:查看 es 健康状况 GET _cluster/health(详细信息 )GET _cluster/health?level=indices(索引级别的详细信息)
GET /_cat/master:查看主节点
GET /_cat/indices:查看所有索引 show databases;
单节点查询health会显示yellow 提示unassigned_shards:1 需要将备份数据改为0
PUT /customer/_settingscustomer是索引
{
"number_of_replicas":0
}
2.索引一个文档(保存) PUT customer/external/1;在 customer 索引下的 external 类型下保存 1 号数据为
PUT customer/external/1
{ "name": "John Doe" }
PUT 和 POST 都可以, POST 新增。如果不指定 id,会自动生成 id。指定 id 就会修改这个数据,并新增版本号 PUT 可以新增可以修改。PUT 必须指定 id;由于 PUT 需要指定 id,我们一般都用来做修改 操作,不指定 id 会报错。
3.查询指定文档 GET customer/external/1
结果
文章图片
1.查询索引信息
GET customer
2.查询对应索引下所有数据
GET customer/external/_search GET(customer/_search)
返回结果
文章图片
4.更新文档
POST customer/external/1/_update
{
"doc":{
"name": "John Doew"
}
}
5.删除文档和索引 DELETE customer/external/1 //删除文档
DELETE customer //删除索引
返回数据:
文章图片
6.bulk 批量 API
POST customer/external/_bulk
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }
返回数据
文章图片
3.进阶检索 1.检索信息
GET bank/_search
{
//查询条件
"query": {
"match_all": {}
},
//检索条件
"sort": [
{
"account_number": {
"order": "desc" //按照auuount_number降序排列
}
}
]
}
结果:默认返回10条数据
文章图片
响应结果解释:
took - Elasticsearch 执行搜索的时间(毫秒)
time_out - 告诉我们搜索是否超时
_shards - 告诉我们多少个分片被搜索了,以及统计了成功/失败的搜索分片
hits - 搜索结果 hits.total - 搜索结果
hits.hits - 实际的搜索结果数组(默认为前 10 的文档)
sort - 结果的排序 key(键)(没有则按 score 排序)
score 和 max_score –相关性得分和最高得分(全文检索用)
2.Query DSL 1.基本语法格式
GET bank/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 5,
"sort": [
{
"account_number": {
"order": "desc"
}
}
]
}
query 定义如何查询,
match_all 查询类型【代表查询所有的所有】,es 中可以在 query 中组合非常多的查 询类型完成复杂查询
除了 query 参数之外,我们也可以传递其它的参数以改变查询结果。如 sort,size
from+size 限定,完成分页功能
sort 排序,多字段排序,会在前序字段相等时后续字段内部排序,否则以前序为准
2.只返回部分字段
GET bank/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 5,
"_source": [
"age",
"balance"
]
}
文章图片
3.match【匹配查询】 1.基本类型(非字符串),精确匹配
只返回account_number为20的数据
GET bank/_search
{
"query": {
"match": {
"account_number": "20"
}
}
}
返回:
文章图片
2.字符串,全文检索
GET bank/_search
{
"query": {
"match": {
"address": "mill"
}
}
}
返回
文章图片
最终查询出 address 中包含 mill 单词的所有记录 match 当搜索字符串类型的时候,会进行全文检索,并且每条记录有相关性得分。
3.字符串,多个单词(分词+全文检索)
GET bank/_search
{
"query": {
"match": {
"address": "mill road"
}
}
}
文章图片
最终查询出 address 中包含 mill 或者 road 或者 mill road 的所有记录,并给出相关性得分。
4.match_phrase【短语匹配】
GET bank/_search
{
"query": {
"match_phrase": {
"address": "mill road"
}
}
}
返回
文章图片
查出 address 中包含 mill road 的所有记录,并给出相关性得分
5.multi_match【多字段匹配】
GET bank/_search
{
"query": {
"multi_match": {
"query": "mill",
"fields": [
"state",
"address"
]
}
}
}
文章图片
查出state 或者 address 包含 mill的数据
6.bool【复合查询】
GET bank/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"address": "mill"
}
},
{
"match": {
"gender": "M"
}
}
],
"should": [
{
"match": {
"address": "lane"
}
}
],
"must_not": [
{
"match": {
"email": "baluba.com"
}
}
]
}
}
}
文章图片
会查出address包含mill(必须),并且gender 是 M(必须),如果address(非必须) 里面有lane最好不过,但是email(必须没有) 必须不包含baluba.com的数据。
7.filter【结果过滤】
并不是所有的查询都需要产生分数,特别是那些仅用于 “filtering”(过滤)的文档。为了不计算分数 Elasticsearch 会自动检查场景并且优化查询的执行。
GET bank/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"address": "mill"
}
}
],
"filter": {
"range": {
"balance": {
"gte": 1000,
"lte": 50000
}
}
}
}
}
}
8.term
和 match 一样。匹配某个属性的值。全文检索字段用 match,其他非 text 字段匹配用 term。
GET bank/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"age": {
"value": "28"
}
}
},
{
"match": {
"address": "990 Mill Road"
}
}
]
}
}
}
9.aggregations(执行聚合)
size:0 不显示搜索数据
aggs:执行聚合。聚合语法如下
“aggs”: {
“aggs_name 这次聚合的名字,方便展示在结果集中”:
{ “AGG_TYPE 聚合的类型(avg,term,terms)”: {} } },
GET bank/_search
{
"query": {
"match": {
"address": "mill"
}
},
"aggs": {
"group_by_state": { //聚合的名字
"terms": {//聚合方式
"field": "age" //聚合的字段
}
},
"avg_age": {//第二个聚合的名字
"avg": {//聚合方式
"field": "age"//聚合的字段
}
}
},
"size": 0
}
文章图片
搜索 address 中包含 mill 的所有人的年龄分布以及平均年龄,但不显示这些人的详情。
按照年龄聚合,并且请求这些年龄段的这些人的平均薪资(聚合嵌套)
GET bank/account/_search
{
"query": {
"match_all": {}
},
"aggs": {
"age_avg": { //父聚合名字
"terms": { //父聚合方式
"field": "age", //父聚合的字段
"size": 1000
},
"aggs": {//子聚合
"banlances_avg": { //子聚合名字
"avg": {//子聚合方式
"field": "balance"//子聚合字段
}
}
}
}
},
"size": 1000
}
文章图片
查出所有年龄分布,并且这些年龄段中 M 的平均薪资和 F 的平均薪资以及这个年龄 段的总体平均薪资
GET bank/account/_search
{
"query": {
"match_all": {}
},
"aggs": {
"age_agg": { //根据年龄聚合 求出各个年龄段的人数
"terms": {
"field": "age",
"size": 100
},
"aggs": {
"gender_agg": { //每个年龄段再根据性别聚合 求出每个年龄段 男和女的人数
"terms": {
"field": "gender.keyword",
"size": 100
},
"aggs": {
"balance_avg": {//每个年龄段的性别再根据工资聚合
"avg": {
"field": "balance"
}
}
}
},
"balance_avg": {//年龄段根据工资聚合
"avg": {
"field": "balance"
}
}
}
}
},
"size": 1000
}
结果返回(其中的一条)
文章图片
4.Mapping 映射 Mapping 是用来定义一个文档(document),以及它所包含的属性(field)是如何存储和 索引的。
哪些字符串属性应该被看做全文本属性(full text fields)。
哪些属性包含数字,日期或者地理位置。
文档中的所有属性是否都能被索引(_all 配置)。
日期的格式。
自定义映射规则来执行动态添加属性。
查看 mapping 信息:GET bank/_mapping
Es7 及以上移除了 type 的概念。 (也就是移除了表的概念,数据直接存在索引下 也就是数据库下)
关系型数据库中两个数据表示是独立的,即使他们里面有相同名称的列也不影响使用, 但 ES 中不是这样的。elasticsearch 是基于 Lucene 开发的搜索引擎,而 ES 中不同 type 下名称相同的 filed 最终在 Lucene 中的处理方式是一样的。
两个不同 type 下的两个 user_name,在 ES 同一个索引下其实被认为是同一个 filed, 你必须在两个不同的 type 中定义相同的 filed 映射。否则,不同 type 中的相同字段 名称就会在处理中出现冲突的情况,导致 Lucene 处理效率下降。
去掉 type 就是为了提高 ES 处理数据的效率。
Elasticsearch 7.x : URL 中的 type 参数为可选。比如,索引一个文档不再要求提供文档类型。 Elasticsearch 8.x :不再支持 URL 中的 type 参数。
解决:将已存在的索引下的类型数据,全部迁移到指定位置即可。详见数据迁移
1.创建索引并指定映射
PUT /my-index
{
"mappings": {
"properties": {
"age": {
"type": "integer"
},
"email": {
"type": "keyword"
},
"name": {
"type": "text"
}
}
}
}
2.添加新的字段映射
PUT /my-index/_mapping
{
"properties": {
"employee-id": {
"type": "keyword",
"index": false
}
}
}
3.更新映射
对于已经存在的映射字段,我们不能更新。更新必须创建新的索引进行数据迁移
4.数据迁移
先创建出 new_twitter 的正确映射。然后使用如下方式进行数据迁移
POST _reindex
{
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter"
}
}
【全文检索|初步检索及进阶检索】将旧索引的 type 下的数据进行迁移
POST _reindex
{
"source": {
"index": "twitter",
"type": "tweet" //指定好原来的type (表)
},
"dest": {
"index": "tweets"
}
}
推荐阅读
- 软件测试|详解软件测试中白盒测试基本概念及四种白盒测试方法
- 运维|jenkins构建maven、git项目部署远程服务器完整过程
- Java修炼之旅|jenkins自动部署maven项目
- java|类和对象(上)——JavaSE
- J2EE|jsp标签
- Java|Spring Cloud微服务分布式架构之组件和概念介绍
- java|《深入理解Spring Cloud与微服务构建》第1章 微服务简介
- 蓝桥杯|40天如何备战2022Java蓝桥杯国赛
- 链表|ArrayList和LinkedList