news 2026/9/28 19:06:41

Elasticsearch的查询

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Elasticsearch的查询

查询返回字段含义

新增一条索引及文档,用_search进行索引查询

返回结果:

{#查询耗时,单位毫秒。这个查询花了1ms 执行(仅ES服务端执行时间,不包含网络传输耗时)"took":1,# 查询是否超时。false没有超时;true代表部分分片查询超时,返回的结果是不完整的。"timed_out":false,# 分片统计"_shards":{# 本次查询一共需要访问1个分片"total":1,# 成功执行返回的分片数量1"successful":1,# 跳过的分片(分片预过滤,不需要查询)"skipped":0,# 查询失败的分片,0代表无分片异常"failed":0},# 命中文档结果集(最核心)"hits":{# 匹配条件的文档总数"total":{# 符合查询条件总共有1条文档"value":1,# eq:精确值,总数就是value;gte:大于等于(ES默认,超过10000条时,不会精确计数,只会告诉你至少多少条,节省性能)"relation":"eq"},# 本次结果集中,最高的相关性打分 _score。这里最高分是1"max_score":1,# 存放每一条命中文档"hits":[{# 文档所属索引名 product"_index":"product",# 文档唯一 id"_id":"1",# 查询上下文的相关性分数。filter 上下文查询这里永远是1.0,不做相关性打分。"_score":1,# 原始文档数据,就是你存入ES的 json 原始内容,默认返回。可以通过_source:false关闭返回,节省带宽。"_source":{"name":"xiaomi phone","desc":"shouji zhong de zhandouji","date":"2021-06-01","price":3999,"tags":["xingjiabi","fashao","buka"]}}]}}

_source过滤

_source是返回文档源数据,支持添加过滤,减少要输出的字段,节约带宽,es底层仍然是读取所有数据,不会提升查询速度。

1、请求体里的_source

  1. 关闭返回 _source
# 关闭_sourceGET/product/_search{"query":{"match_all":{}},"_source":false}

  1. 数组,指定要返回哪些字段
# 数组指定返回字段:name、priceGET/product/_search{"query":{"match_all":{}},"_source":["name","price"]}

  1. 对象形式includes + excludes,支持通配符*
GET/product/_search{"query":{"match_all":{}},"_source":{"includes":["name","desc","company.*"],"excludes":["desc"]}}

  • includes:包含的字段(白名单)
  • excludes:从白名单里再剔除字段(黑名单)
    支持嵌套对象写法:user.address.city,通配符obj.*

2、URL 查询参数

用法同写在请求体中一样

  • _source_includes=name,price
  • _source_excludes=desc,date
# 查询prouct索引的所有文档记录,_source中只返回包含d开头的字段,排除descGET/product/_search?_source_includes=d*&_source_excludes=desc

3、Mapping 层面永久过滤

在索引 mapping 中定义_source.includes/_source.excludes,索引存储时就移除字段,无法恢复,一般不推荐业务使用

PUTproduct{"mappings":{"_source":{"includes":["name"],"excludes":["desc"]}}}

GET查询

通过get index/_search可以直接查询数据

# 查询索引中全部记录GET/product/_search # 等价于GET/product/_search{"query":{"match_all":{}}}

带查询条件

# 查询prduct索引中,name包含xiaomi的文档GET/product/_search?q=name:xiaomi # 等价于GET/product/_search{"query":{"match":{"name":"xiaomi"}}}

带分页

# 查询prduct索引中,name包含xiaomi的文档,跳过0条,取2条GET/product/_search?q=name:xiaomi&from=0&size=2# 等价于GET/product/_search{"query":{"match":{"name":"xiaomi"}},"from":0,"size":2}

带排序

# 查询prduct索引中,name包含xiaomi的文档,跳过0条,取2条,按price降序GET/product/_search?q=name:xiaomi&from=0&size=2&sort=price:desc # 等价于GET/product/_search{"query":{"match":{"name":"xiaomi"}},"from":0,"size":2,"sort":[{"price":{"order":"desc"}}]}

在所有支持索引查询的字段查询

# 查询product索引中,所有排序字段带xiaomi的文档GET/product/_search?q=xiaomi # 等价于GET/product/_search{"query":{"query_string":{"query":"xiaomi"}}}

日期字段查询,日期字段不会分词。

# 查询product索引中,所有排序字段带xiaomi的文档GET/product/_search?q=date:2021-06-01# 等价于GET/product/_search{"query":{"query_string":{"query":"date:2021-06-01"}}}

match查询

match 查询会对查询条件分词,只要索引字段有能匹配的字段就能查到

# 查询索引product,name字段包含小米的文档GET/product/_search{"query":{"match":{"name":"xiaomi"}}}# 查询索引product,name字段,包含 xiaomi 或 nfc 或 phone 的文档GET/product/_search{"query":{"match":{"name":"xiaomi nfc phone"}}}

查询条件“xiaomi nfc phone”也会被分词,只要有一个词匹配就算匹配成功。默认按评分字段‘_score’排序,匹配的越多,排序越靠前。

match_all查询

match_all匹配全部文档。它本身不支持写字段条件,它只有两个可选参数:boost、_name。

{"match_all":{"boost":1.2,// 给这个查询的分数加权,默认1.0"_name":"all"// 查询命名,用于profile/命中标记,调试用}}

multi_match查询

在多个字段中全文搜索,查询条件会分词,只要有一个条件匹配就返回

# 查询索引中,name或desc字段包含xiaomi 或 nfc 或 phone 的文档GET/product/_search{"query":{"multi_match":{"query":"xiaomi nfc phone","fields":["name","desc"]}}}

match_phrase 查询

match_phrase 会对检索文本分词,要求分词后的词在文档中连续、并且顺序一致,还可以控制词之间允许的间隔 slop。

# 查询索引中,name字段包含xiaomi phone短句的文档,xiaomi和phone都存在且连续、顺序一致。GET/product/_search{"query":{"match_phrase":{"name":"xiaomi phone"}}}

trem-精确匹配

于match查询不同,trem查询不会对要查询的字段进行分词,要求文档中对应字段完全包含才会匹配。

# 匹配 name为“xiaomi phone” 的文档GET/product/_search{"query":{"term":{"name":"xiaomi phone"}}}# 等价于GET/product/_search{"query":{"term":{"name":{"value":"xiaomi phone"}}}}

注意:text类型的name为“xiaomi phone”的数据不能被term匹配,因为存储时会被分词,不能用于精确匹配。

match_phrase和term的区别

match_phrase会对搜索条件分词,只要分词后的词条在目标文档的倒排索引中都存在、连续且顺序一致就能被检索。
term不会对查询条件分词,需要目标文档字段字段的倒排索引存在完整的文本才能被检索。

terms查询

terms相当于同时精确匹配多个查询条件,相当于in。

# 查询tags字段包含lowbee或zhong的文档GET/product/_search{"query":{"terms":{"tags":["lowbee","zhong"]}}}

range查询

range用户范围查询,用于数值、日期、ip类型的查询,text/keyword 一般不用于 range。

# 查询price大于等于2999并且小于等于4999的文档GET/product/_search{"query":{"range":{"price":{"gte":2999,"lte":4999}}}}# 查询日期 大于2021-06-01且小于2021-06-03的文档GET/product/_search{"query":{"range":{"date":{"gt":"2021-06-01","lt":"2021-06-03"}}}}

es中提供了对日期的计算方法:
锚点日期 +||+ 运算,锚点可以是now或者写死日期字符串Elastic
支持:+(加)、-(减)、/(向下舍入 / 取整),单位支持:y年、M月、w周、d天、h小时、m分钟、s秒

"gte":"now-1d",// 当前时间 -1天"gte":"2021-06-01||+1M"// 2021-06-01 加1个月"gte":"2021-06-01||/d"// 舍入到当天零点(向下取整天)"gte":"now||/M"// 舍入到当月第一天零点

bool查询

bool是复合查询(Compound Query),本身不直接匹配文档,作用是组合多个子查询,通过 4 个子句来控制多个条件之间的逻辑关系(AND / OR / NOT)。
核心:把多个小查询(term/range/match 等)拼装在一起,并且区分查询上下文(算分)和过滤上下文(不算分)。

子句逻辑含义上下文是否算_score
must必须满足(AND)查询上下文✅ 参与打分
should可以满足(OR)查询上下文✅ 满足就加分
filter必须满足(AND)过滤上下文❌ 不打分,可缓存
must_not必须不满足(NOT)过滤上下文❌ 不打分,可缓存
  1. must:条件一定要成立,并且这个条件会参与相关性打分。
  2. filter:条件一定要成立,但是不参与打分,ES 会尝试缓存,性能更好;纯筛选条件优先放 filter。
  3. must_not:条件一定不能成立,过滤上下文,不打分。
  4. should:可选条件,满足的文档分数更高。
    • 如果 bool 里没有 must /filter:should 至少满足 1 条才算命中;
    • 如果 bool 里有 must /filter:should 只是加分项,不强制满足。

must + filter示例

name 必须匹配 xiaomi(全文检索打分),并且价格≥3000(过滤,不打分)

# name有xiaomi,价格大于3000GETproduct/_search{"query":{"bool":{"must":[{"match":{"name":"xiaomi"}}],"filter":[{"range":{"price":{"gte":3000}}}]}}}

should

匹配 name 含 xiaomi或者tags 是 xingjiabi

# 名字包含xiaomi 或者tags包含xingjiabiGET/product/_search{"query":{"bool":{"should":[{"match":{"name":"xiaomi"}},{"term":{"tags":"xingjiabi"}}],"minimum_should_match":1}}}

minimum_should_match:should 最少需要满足几条。当 bool 没有 must/filter 时,默认值是 1。有must/filter时默认等于0,满足只做加分。

must_not 排除

只排除数据不参与评分

# 价格不能大于5000GET/product/_search{"query":{"bool":{"must_not":[{"range":{"price":{"gte":5000}}}]}}}

bool嵌套

# 从tags包含xingjiabi或价格小于等于4000的数据中筛选name包含xiaomi的文档GETproduct/_search{"query":{"bool":{"must":[{"match":{"name":"xiaomi"}}],"filter":[{"bool":{"should":[{"term":{"tags":"xingjiabi"}},{"range":{"price":{"lte":4000}}}]}}]}}}

filter过滤数据,包含一个子查询:tags包含xingjiabi或者价格小于等于4000,再匹配name中包含xiaomi

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 19:06:28

2026年乐清原创全屋木作服务商怎么选?五家实测对比与避坑指南

第一章 乐清原创全屋木作:从“打柜子”到“整案交付” 乐清原创全屋木作,简单说就是本地设计、本地拆单、本地生产、本地安装的一体化木作服务。它和传统成品柜最大的区别,是把门、墙、柜、护墙板、橱柜、衣柜、玻璃柜门、家政柜等纳入同一套…

作者头像 李华
网站建设 2026/9/28 19:05:23

用 VSCODE 编译 STM32 固件:从 tasks.json 到 TaoToken 的配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 19:04:51

工控现货:产线停机危机下的实时备件响应体系

1. 什么是“工控现货”:不是电商标签,而是产线命脉的实时响应能力“工控现货”这四个字,最近在自动化工程师的朋友圈、设备采购群、甚至维修师傅的茶余饭后频繁出现。它不是某个新出的电商平台分类,也不是营销话术里的“限时抢购”…

作者头像 李华