文章十七:ElasticSearch get\search查询相关参数

Get查询:

get查询的特点

  • 数据写入先存 IndexBuffer + Translog,此时 Get 可查、Search 不可查。
  • 执行 Refresh 后,Buffer 数据生成 Segment 写入系统文件缓存
  • 只有落地到文件缓存、构建完倒排索引,Search 才能查询到。
  • 自动刷新间隔默认 1s,因此 ES 查询是近实时。

两种查询方式:

复制代码
GET citibike-202201/_doc/63AF72AB3CD47753?preference=_local&routing=afd&refresh=false&version=1&stored_fields=*&realtime=true


GET  /citibike-202201/_mget
{
  "docs":[
    {
      "_id":"63AF72AB3CD47753"
    },
    {
      "_id":"63AF72AB3CD47753"
    }
    ]
}

Search查询

allow_no_indices:

在使用通配符进行查询时,是否允许索引不存在,默认是不允许的

GET citibike-202201,index_test*/_search?allow_no_indices=true

from 和 size实现分页:

GET citibike-202201/_search?from=110&size=100

batched_reduce_size:

在使用通配符进行匹配时,防止因为查询分片过多,造成我们的es服务器出现问题,我们在查询时,可以设定一下最多的查询分片数,使用字段batched_reduce_size进行设置

GET citibike-202201*/_search?batched_reduce_size=10

search_type

1. query_then_fetch(默认)

  • 流程(两阶段)
    1. 协调节点广播查询到所有相关分片;
    2. 各分片本地算分(只用自己分片的词频),返回「文档 ID + 分数」;
    3. 协调节点全局排序,取前 size 个;
    4. 再去对应分片批量拉取完整文档内容返回给客户端。
  • 特点
    • :只需 1 轮分片往返,算分用本地词频;
    • ⚠️ 算分不准:不同分片词频独立,跨分片相关性对比有偏差Elastic。
  • 适用:绝大多数场景(日志、监控、普通检索),追求速度优先Elastic。

2. dfs_query_then_fetch

  • 流程(三阶段)
    1. 预查询(DFS):协调节点先问所有分片要「全局词频统计」;
    2. 全局算分 :用全分片合并后的全局词频,再广播查询;
    3. 后续同 query_then_fetch:分片返回 ID + 分数 → 协调节点排序 → 拉取文档。

track_total_hits

track_total_hits=true 用于强制 Elasticsearch 精确统计本次检索命中的全部文档总数,放弃默认的近似总数优化逻辑,以额外的性能开销为代价,返回完全准确的匹配数据总量。

GET citibike-202201*/_search?track_total_hits=true

sort

使用sort指定字段排序

GET page_study_index/_search?sort=number&from=10&size=100

scroll

scroll 是 Elasticsearch 用于高效批量获取大量数据的游标机制,核心作用是避免深分页导致的性能损耗,它会在服务端创建一个数据快照并保持搜索上下文,通过游标逐批读取数据,直到获取全部结果。使用时需要先发起带 scroll 参数的初始化搜索请求,指定上下文保留时间,请求会返回第一批数据和一个 _scroll_id 游标标识。后续所有数据读取都通过 _scroll API 提交该游标标识,无需重复执行查询条件,Elasticsearch 会基于之前的上下文持续返回下一批数据。每次请求都会沿用服务端的快照数据,保证数据一致性,不会受到索引实时写入、更新的影响。应用场景主要集中在全量数据导出、批量数据迁移、大数据量统计分析等需要获取上万甚至百万级文档的操作,替代 from+size 深分页方案。使用完成后必须主动清除 scroll 上下文释放服务端资源,避免占用内存造成性能影响,在实际开发中,它是处理海量非实时数据的标准方案,而普通的前端分页查询则不建议使用 scroll。

第一步:初始化 scroll

复制代码
GET 你的索引名/_search?scroll=1m
{
  "size": 100,
  "query": {
    "match_all": {}
  }
}
  • scroll=1m:让 ES 保留搜索上下文 1 分钟
  • size: 每一批返回多少条(比如 100)
  • 第一次执行后,会返回两个关键东西:
    1. _scroll_id:游标 ID(很长一串字符串)
    2. 第一批 100 条数据

第二步:循环滑动游标(取下一批数据)

复制代码
POST _search/scroll
{
  "scroll": "1m",
  "scroll_id": "这里换成第一步返回的scroll_id"
}

含义

  • 不需要再带索引名、查询条件
  • 只需要传 scroll_id + 保留时间
  • 每次执行,都会返回下一批数据
  • 一直执行,直到 hits 为空,代表读完了

第三步:用完必须删除游标(释放资源)
复制代码
DELETE _search/scroll
{
  "scroll_id": "你的游标ID"
}

含义

  • scroll 会占用 ES 内存
  • 不删会导致性能下降
  • 读完数据必须清理

使用es进行格式转换:

通过下面的方式对于时间格式进行转换

GET citibike-202201/_search

{

"fields": [

{

"field": "started_at",

"format": "yyyy-mm-dd"

}

]

}

使用脚本的方式处理数据

GET citibike-202201/_search

{

"_source": ["*"],

"script_fields": {

"my_result": {

"script": {

"source": """

params._source.rideable_type + params._source.end_station_id;

"""

}

}

}

}

script_fields里面的数据只能用于结果展示用 → 不能排序、不能统计

runtime_mappings

runtime_mappings(运行时字段) :是「真・字段」,可以排序、可以聚合、可以过滤、可以查询,和普通字段用法几乎一样Elastic。

runtime_mappings = 运行时临时字段

  • 只在当前这一次查询中生效
  • 不会修改数据、不会写入磁盘、不会保存到索引里
  • 查询结束就消失,下次查询要重新定义

GET citibike-202201/_search
{
"runtime_mappings": {
"runtime_text_name": {
"type": "keyword",
"script": {
"source": """
emit(params._source.rideable_type + params._source.end_station_id);
"""
}
}
},
"fields": ["runtime_text_name"], 加上这个才可以显示出来我们运行时计算的字段
"_source": false
}

异步方式

POST citibike-202201/_async_search?timeout=1ms

_pit查询:

我们在实际的查询过程中,因为数据的改变每次返回的数据可能是不一致的,但是如果我们在使用_pit进行查询时可以设置结果多久不会变。

下面的例子中展示了保证结果一分钟不改变

POST citibike-202201/_pit?keep_alive=1m

完整查询语句

http

复制代码
POST /_search
{
  "size": 10,
  "query": {
    "match_all": {}
  },
  "pit": {
    "id": "把你刚才获取的PIT-ID粘贴在这里",
    "keep_alive": "1m"
  }
}

关键规则(必须遵守)

  1. 查询地址 :必须用 POST /_search不能带索引名
  2. 必传参数pit.id 填你获取的 ID
  3. 延长有效期pit.keep_alive 每次查询都会刷新快照有效期
  4. 结果一致性
    • 1 分钟内,无论索引数据怎么变,查询结果完全一致
    • 超时后 PIT 自动失效,无法再使用

完手动删除 PIT(推荐)

PIT 会占用内存,不用了可以手动删除:

复制代码
DELETE /_pit
{
  "id": "你的PIT-ID"
}
相关推荐
王八八。6 小时前
linux后台java、postSQL部署命令
java·linux·运维
月落归舟6 小时前
MyBatis缓存机制
java·缓存·mybatis
huipeng9266 小时前
企业级微服务开发实战(一):项目启动与工程化设计
java·开发语言·spring boot·spring cloud·微服务·云原生·架构
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ7 小时前
java实现excel导入、下载模板方法
java·开发语言·excel
黎阳之光8 小时前
黎阳之光:以视频孪生重构智慧防火,打造“天空地人智”一体化森林防火新范式
大数据·运维·人工智能·物联网·安全
段ヤシ.8 小时前
回顾Java知识点,面试题汇总Day12(持续更新)
java·mybatis
java1234_小锋8 小时前
Spring AI 2.0 开发Java Agent智能体 - MCP(模型上下文协议)
java·人工智能·spring·spring ai
seven97_top8 小时前
两小时入门Sentinel
java·sentinel
叶小鸡8 小时前
Java 篇-项目实战-AI 天机学堂(从 0 到 1)-day1
java·开发语言
bigbearxyz8 小时前
Caused by: java.net.SocketException: Connection reset问题排查
java·keepalived·proxysql