前言
本文记录 ES 的一些基本操作,就是对官方文档的一些整理,按自己的习惯重新排版,凑合着看。官方的更详细,建议看官方的。
下文以 books 为索引名举例。
新增
添加单个文档 (没有索引会自动创建)
            
            
              json
              
              
            
          
          POST books/_doc
{"name": "Snow Crash", "author": "Neal Stephenson", "release_date": "1992-06-01", "age": 18}不指定 id,会随机生成,如果需要指定 id,使用 POST books/_doc/id
还可以使用 put 的方式新增,例入 POST books/_doc/id,这种方式必须带 id,否则会报错
以上两种方式,如果带上了 id,就是不存在就插入,存在旧更新
更新
总结 (有三种方式):
- POST 更新
- 如果 URL 带 _update,更新前会对比新旧数据,如果新旧数据完全相同,将不会进行任何操作 noop,不会影响序列号、版本号信息。
- 如果 URI 不带 _update,不会检查原数据,都会显示 updated
 
- 如果 URL 带 
- PUT 更新
- 路径没法带 _update,每次都会更新显示 updated
 
- 路径没法带 
例如有原数据
            
            
              json
              
              
            
          
          {
	"name": "zhangsan",
	"age": 18
}POST 访问:(路径带_update)
需要在参数外套一层 doc,这种方式不影响其他字段
            
            
              json
              
              
            
          
          POST /books/_update/1
{
    "doc": {
        "name": "lisi"
    }
}
// 执行之后原数据变成
{
	"name": "lisi",
	"age": 18
}POST 访问:(路径不带_update)
和带 id 新增的语法是一样的,不存在就是插入,存在就是更新。这种方式会清空其他字段
            
            
              json
              
              
            
          
          POST /books/_doc/1
{
    "name": "lisi"
}
// 执行之后原数据变成
{
	"name": "lisi"
}PUT 访问:(路径不能带_update)
效果同第 2 点
            
            
              json
              
              
            
          
          PUT /books/_doc/1
{
    "name": "lisi"
}删除
            
            
              json
              
              
            
          
          DELETE /books/_doc/1
POST /books/_delete_by_query
{查询条件...}搜索
官方实例数据:account. json
使用 [Bulk API](Bulk API | Elasticsearch Guide [8.12] | Elastic) 来批量插入,没有安装 kibana 也可以用 postman 导入

如果插入记录搜索不到,可能是索引未来得及刷新,可以手动触发
POST /article/_refresh
根据 id 获取文档
            
            
              json
              
              
            
          
          // 获取带元数据的
GET /bank/_doc/1
// 获取不带元数据的
GET /bank/_source/1
// 判断文档是否存在
HEAD /bank/_doc/1使用 HEAD 只会返回 {} 空对象,可以根据请求是否 404 判断文档是否存在
_search 命令搜索
注意:如果你用 es-client 连接的 es,请将 GET 换成 POST,否则查询无效
原因是 GET 请求没有带上 body 参数
默认只会返回最先匹配到的 10 条文档
            
            
              json
              
              
            
          
          GET /bank/_search返回结果:
took:检索花费时间,单位毫秒(从节点收到查询到将数据返回客户端之前)
timed_out: 布尔类型,检索是否超时
hits: 命中的记录
total.value: 总记录的数量
hits.total: 所有命中的记录
搜索全部
            
            
              json
              
              
            
          
          GET /bank/_search
{
    "query": {
        "match_all": {}
    }
}排序
Sort search results | Elasticsearch Guide [8.12] | Elastic
            
            
              json
              
              
            
          
          GET /bank/_search
{
    "sort": [
        {
            "account_number": "desc"
        },
        {
            "balance": { // 两种写法都行
                "order": "asc"
            }
        }
    ]
}sort :排序条件,先对 account_number 降序,如果 account_number 相同,再对 balance 升序
其他排序参数
            
            
              json
              
              
            
          
          GET /bank/_search
{
    "sort": [
        {
            "arr": {
                "order": "desc", // 排序
                "mode": "min", // 排序模式
                "missing": "_last" // 缺失值处理
            }
        }
    ]
}排序模式
用于对数组或多值字段排序。比如有数据如下
            
            
              json
              
              
            
          
          {
    "age": 25,
    "arr": [
        11000,
        23234
    ]
}arr 字段就是多值字段。
升序排序的默认排序模式是 min 。默认的降序排序模式是 max
| mode | 说明 | 
|---|---|
| min | 选择最低值 | 
| max | 选择最高值 | 
| sum | 总和作为排序值 | 
| avg | 平均值作为排序值 | 
| median | 中位数作为排序值 | 
缺失值处理
顾名思义,就是排序时,没有该字段的文档排前面还是排后面。
missing 值可以设置为 _last 、 _first,默认为 _last
分页
Paginate search results | Elasticsearch Guide [8.12] | Elastic
| 查询方式 | 数据量 | 实时查询 | 排序 | 跳页 | 适用场景 | 
|---|---|---|---|---|---|
| form+size 浅分页 | 小 | 支持 | 支持 | 支持 | 实时查询,跳页查询 | 
| scroll 标准方式 | 大 | 不支持 | 支持 | 不支持 | 深度分页,有序的批量查询 | 
| scroll_scan 滚动扫描 | 大 | 不支持 | 不支持 | 不支持 | 深度分页,无需的批量查询 | 
| search_after 分页 | 大 | 支持 | 支持 | 不支持 | 深度分页,数据批量导出 | 
from + size
默认返回前 10 个结果。可以使用 from 和 size 参数,from 定义要跳过的命中数,默认 0,size 是返回的最大命中数。类比 mysql 中的 limit 0,10
默认情况下,无法使用 from 和 size 来翻阅超过 10,000 个匹配项。也就是前 10000 条数据可以用这种方式分页。如果数据太多,请使用search_after
            
            
              json
              
              
            
          
          GET /bank/_search
{
    "from": 0,
    "size": 10
}search_after
注意:搜索必须指定排序字段,否则获取不到 search_after 需要的参数。
使用步骤:
一、第一页不需要使用 search_after
            
            
              json
              
              
            
          
          // 查询
GET /bank/_search
{
    "sort": [ // 必须指定排序字段
        "account_number",
        "age"
    ]
}
// 响应
{
    ...
    "hits": {
        ...
        "hits": [
            {
                ...
                "sort": [ 0, 29]
            }
        ]
    }
}第二页的搜索,就带上前一页的 hits.sort 中的参数
            
            
              json
              
              
            
          
          GET /bank/_search
{
	"search_after": [0, 29],
    "sort": [ // 必须指定排序字段
        "account_number",
        "age"
    ]
}TODO PIT
A 查询数据,B 同时在插入数据,为了解决 A 两次查询的数据不一致,可以使用 point int time
检索选定的字段
Retrieve selected fields from a search | Elasticsearch Guide [8.12] | Elastic
关键词 fields,可以指定返回字段和格式
搜索 API
Query DSL | Elasticsearch Guide [8.12] | Elastic
Search API | Elasticsearch Guide [8.12] | Elastic
query 和 filter
query 就是普通的查询,会计算分数。
filter 不会计算分数,es 还会自动缓存常用的过滤器提高性能
说明:Query and filter context | Elasticsearch Guide [8.12] | Elastic
用法:Boolean query | Elasticsearch Guide [8.12] | Elastic
复合查询
Compound queries | Elasticsearch Guide [8.12] | Elastic
全文查询
intervals 文本灵活查询
Intervals query | Elasticsearch Guide [8.12] | Elastic
允许用户精确控制查询词在文档中出现的先后关系,实现了对 terms 顺序、terms 之间的距离以及它们之间的包含关系的灵活控制
match 模糊查询
Match query | Elasticsearch Guide [8.12] | Elastic
对基本类型,是精确匹配(比如 long、日期等)。对字符串是模糊查询,对查询的值分词,对分词的结果一一进入倒排索引去匹配
            
            
              json
              
              
            
          
          GET /ft/_search
{
    "query": {
        "match" : {
            "my_text":{
                "query": "my when",
                "operator": "or"
            }
        }
    }
}解释:查找 my_text 字段中包含 my 或者 when 的文档。
query: 需要查询的内容
operator:默认是 or,如果改成 and,就需要 my_text 中同时包含 when 和 my
analyzer:分词器,默认使用字段的分词器
prefix 前缀查询
            
            
              json
              
              
            
          
          GET /ft/_search
{
    "query": {
        "prefix": {
            "my_text": {
                "value": "favo"
            }
        }
    }
}匹配 my_text 中以 favo 开头的,注意是不能分词的,也就是 my fa 查不到 cold my favourite food,但是用 favo 可以找到
match_bool_prefix 分词前缀查询
prefix 不能分词,那么 match_bool_prefix 就来了
            
            
              json
              
              
            
          
          GET /ft/_search
{
    "query": {
        "match_bool_prefix": {
            "my_text": {
                "query": "quick brown f"
            }
        }
    }
}解释:先分词,最后一个词按前缀处理,前面的词语直接匹配,只要有一个命中就可以
匹配 quick brown fox 和 two quick brown ferrets 和 the fox is quick and brown
match_phrase 短语匹配查询
顾名思义,match 会分词,match_phrase 不会分词
            
            
              json
              
              
            
          
          GET /ft/_search
{
    "query": {
        "match_phrase": {
            "my_text": {
                "query": "wo shi"
            }
        }
    }
}match_phrase_prefix 短语前缀匹配查询
            
            
              json
              
              
            
          
          GET /ft/_search
{
  "query": {
    "match_phrase_prefix": {
      "my_text": {
        "query": "quick brown f"
      }
    }
  }
}与 match_bool_prefix 的区别就是不分词,匹配 quick brown fox 和two quick brown ferrets,不匹配 the fox is quick and brown
combined_fields 组合多字段查询
Combined fields | Elasticsearch Guide [8.12] | Elastic
这个有点不太理解。
            
            
              json
              
              
            
          
          GET /ft/_search
{
    "query": {
        "combined_fields": {
            "query": "ren shui",
            "fields": [
                "title",
                "my_text"
            ],
            "operator": "and"
        }
    }
}解释:效果类似于将 title 和 my_text 两个字段合并成一个,再执行查询
注意,我把 operator 改成 and 了,但是只要 title 和 my_text 组合起来,包含了 ren 和 shui 就能命中
multi_match 多字段查询
Multi-match query | Elasticsearch Guide [8.12] | Elastic
在 match 查询的基础上,允许多字段查询
            
            
              json
              
              
            
          
          GET /ft/_search
{
    "query": {
        "multi_match": {
            "query": "ren shui",
            "fields": [
                "title",
                "my_text"
            ],
            "operator": "and"
        }
    }
}解释:我把 operator 改成了 and,那么需要 title 同时包含 ren 和 shui 两个词,或者 my_text 同时包含两个词,才能命中。和 combined_fields 有区别的。
总结
没啥好总结的,吐槽一句,官方文档对新手不太友好。新手需要的是快速使用,怎么调 api
参考
【ElasticSearch(四)】PUT&POST更新数据、DELETE删除数据、_bulk批量操作 - musecho - 博客园 (cnblogs.com)