写点什么

大数据 -174 Elasticsearch 查询 DSL 实战:match/match_phrase/query_string/multi_match 全解析

作者:武子康
  • 2025-12-06
    山东
  • 本文字数:3636 字

    阅读完需:约 12 分钟

大数据-174 Elasticsearch 查询 DSL 实战:match/match_phrase/query_string/multi_match 全解析

TL;DR

  • 场景:在 Elasticsearch 7.3 中用查询 DSL 做全文检索,而不是靠 Kibana 点选和简单关键字搜索。

  • 结论:区分 match、match_phrase、query_string、multi_match 的匹配边界和分词语义,是中文搜索是否“搜得到”的关键。

  • 产出:一套可直接复制的 DSL 示例与排错思路,覆盖中文分词、逻辑查询、多字段匹配和常见“查不到数据”的问题定位。


版本矩阵


官方地址

https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl.html
复制代码


Elasticsearch 提供了基于 JSON 的完整查询 DSL(Domain Specific Language 特定域语言)来定义查询,将查询 DSL 视为查询 AST(抽象语法树),它由两种子句组成:


  • 叶子查询句 叶子查询子句 在特定域中寻找特定的值,如 match、term、range 查询

  • 复合查询子句 复合查询子句包装其他叶子查询或复合查询,并用于以逻辑方式组合多个查询(例如 bool 或 dis_max 查询),或更改其行为(如 constant_score 查询)我们在使用 Elasticsearch 的时候,避免不使用 DSL 语句去查询,就像使用关系型数据库的时候要学会使用 SQL 一样。

查询所有

示例


# 查询所有数据POST /wzkicu-index/_search{  "query":{    "match_all": {}  }}
复制代码


  • query 代表查询的对象

  • match_all 代表查询所有


执行后,结果如下:



结果中:


  • took 查询花费时间,单位是毫秒

  • time_out 是否超时

  • _shards 分片信息

  • hits 搜索结果总览对象

  • total 搜索到的总数

  • max_score 所有结果中文档得分的最高分

  • _index 索引库

  • _type 文档类型

  • _id 文档 id

  • _score 文档得分

  • _source 文档的数据源

全文检索(full-text query)

全文搜索能够搜索已分析的文本字段,如电子邮件正文、商品描述,使用索引期间应用于字段的同一分词处理查询字符串,全文搜索的分类很多,有如下的这么几种。

匹配搜索(match query)

全文查询的标准查询,查询条件比较宽松:


  • 需要指定字段名

  • 输入文本会进行分词,比如 hello world,会拆分成 hello 和 world,然后进行匹配,如果字段内容中包含 hello 或者 world,name 就会被查询出来。也就是说 match 是一个部分匹配的模糊查询。


match queries 接收 text/numerics/dates,对它们进行分词分析,再组织成一个 boolean 查询,可通过 operator 指定 bool 组合操作(or、and、默认是 or)。


假设一个案例,目前索引库中,有两部手机,一台电视:先新增索引库:


# 创建索引PUT /wzk-property{  "settings": {},  "mappings": {    "properties": {      "title": {        "type": "text",        "analyzer": "ik_max_word"      },      "images": {        "type": "keyword"      },      "price": {        "type": "float"      }    }  }}
复制代码


执行的结果如下图所示:



接着我们写入一些数据进去:


# 添加数据1POST /wzk-property/_doc/{  "title": "小米电视4A",  "images": "https://profile-avatar.csdnimg.cn/755ff10be62f4e7081bc36028fa9eafe_w776341482.jpg!1",  "price": 4288}
# 添加数据2POST /wzk-property/_doc/{ "title": "小米手机", "images": "https://profile-avatar.csdnimg.cn/755ff10be62f4e7081bc36028fa9eafe_w776341482.jpg!1", "price": 2699}
# 添加数据3POST /wzk-property/_doc/{ "title": "华为手机", "images": "https://profile-avatar.csdnimg.cn/755ff10be62f4e7081bc36028fa9eafe_w776341482.jpg!1", "price": 5699}
复制代码


执行结果如下图所示:



我们进行 or 关系的 match 搜索,会把查询条件进行分词,然后进行查询,多个词条之间是 or 的关系:


# match 分词匹配POST /wzk-property/_search{  "query":{    "match":{      "title":"小米电视4A"    }  }}
复制代码


执行结果如下图所示:



我们可以看到,不仅查到了小米电视、还查询到了小米手机。这不是我们要的结果。此时我们需要使用 and 的方式来进行精确的查找:


# match 分词匹配 title字段 同时 分词后的每个词 都要匹配到才可以(and)POST /wzk-property/_search{"query":  {    "match": {      "title":      {        "query": "小米电视4A",        "operator": "and"      }    }  }}
复制代码


执行结果如下,可以看到已经精准匹配到了:


短语搜索(match phrase query)

match_query 是分词的,text 也是分词的,match_phrase 的分词结果必须在 text 字段中都包含,而且顺序必须相同,而且必须是连续的:


# 分词匹配但考虑顺序# match是不考虑分词出现的顺序# match_phrase 将遵循分词的出现顺序才进行匹配POST /wzk-property/_search{  "query": {    "match_phrase": {      "title": "小米电视"    }  }}
复制代码


执行结果如下图所示:



# match_phrase 分伺后:1电视 2小米# 因为条目中 小米电视的出现不是 1、2,所以没有匹配到POST /wzk-property/_search{  "query": {    "match_phrase": {      "title": "电视小米"    }  }}
复制代码


执行结果如下图所示:



# match_phrase 分词 1是小米 2是4A# 但是由于 原:小米电视4A,对比中没有严格按照1、2的顺序# 所以没有结果POST /wzk-property/_search{  "query": {    "match_phrase": {      "title": "小米4A"    }  }}
复制代码


执行结果如下图所示:



但是对于刚才的结果,可能我们希望使用 小米 4A,可以按照 match_phrase 的顺序来查找到 小米电视 4A,而不用严格遵守顺序,可以跳过几个词:


# 通过 slop 可以跳过一个词 来让 match_phrase 匹配到顺序的结果POST /wzk-property/_search{  "query": {    "match_phrase": {      "title": {        "query": "小米4A",        "slop": 1      }    }  }}
复制代码

query_string 查询

该查询与 match 类似,但是 match 需要指定字段名,query_string 是在所有字段中搜索,范围更广泛。Query String Query 提供了无需指定某字段而对文档全文进行匹配查询的一个高级查询,同时可以指定在哪些字段上进行匹配。


# 广泛查询 所有字段中查找 2699POST /wzk-property/_search{  "query": {    "query_string": {      "query": "2699"    }  }}
复制代码


执行结果如下图所示:



# 广泛查找 但是你希望从这个default_field字段中查找POST /wzk-property/_search{  "query": {    "query_string": {      "query": "2699",      "default_field": "title"    }  }}
复制代码


执行结果如下图所示:



# 逻辑查询 使用 OR 或者 ANDPOST /wzk-property/_search{  "query": {    "query_string": {      "query": "手机 OR 小米",      "default_field": "title"    }  }}
复制代码


执行结果下图所示:



# 逻辑查询 使用 OR 或者 ANDPOST /wzk-property/_search{  "query": {    "query_string": {      "query": "手机 AND 小米",      "default_field": "title"    }  }}
复制代码


执行结果如下图所示:



# 模糊查询,表示 小米 这个词可以有1个词变动# 比如:小明、米小 都是可以查询出来的POST /wzk-property/_search{  "query": {    "query_string": {      "query": "小米~1",      "default_field": "title"    }  }}
复制代码


执行结果如下图所示:



# 模糊查询,表示 小米 这个词可以有1个词变动# 比如:小明、米小 都是可以查询出来的# 以此类推,如果是 小米~2 那就两个词都可以变动...POST /wzk-property/_search{  "query": {    "query_string": {      "query": "米小~1",      "default_field": "title"    }  }}
复制代码


执行结果如下图所示:



# 多字段支持POST /lagou-property/_search{  "query": {    "query_string" : {      "query":"2699",      "fields": [ "title","price"]    }  }}
复制代码


执行结果如下图所示:


多字段匹配查询(multi match query)

如果你需要在多个字段上进行文本搜索,可用 multi_match,multi_match 在 match 的基础上支持对多个字段进行文本查询。


# multi_match 是 match查询的一种扩展方式,用于在多个字段上进行查询POST /wzk-property/_search{  "query": {    "multi_match" : {      "query":"小米4A",      "fields": [ "title","images"]    }  }}
复制代码


执行结果如下图所示:


错误速查

其他系列

🚀 AI 篇持续更新中(长期更新)

AI 炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用 AI 工具指南!AI 研究-132 Java 生态前沿 2025:Spring、Quarkus、GraalVM、CRaC 与云原生落地🔗 AI模块直达链接

💻 Java 篇持续更新中(长期更新)

Java-180 Java 接入 FastDFS:自编译客户端与 Maven/Spring Boot 实战 MyBatis 已完结,Spring 已完结,Nginx 已完结,Tomcat 已完结,分布式服务已完结,Dubbo 已完结,MySQL 已完结,MongoDB 已完结,Neo4j 已完结,FastDFS 已完结,OSS 正在更新... 深入浅出助你打牢基础!🔗 Java模块直达链接

📊 大数据板块已完成多项干货更新(300 篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT 案例 详解🔗 大数据模块直达链接

发布于: 刚刚阅读数: 3
用户头像

武子康

关注

永远好奇 无限进步 2019-04-14 加入

Hi, I'm Zikang,好奇心驱动的探索者 | INTJ / INFJ 我热爱探索一切值得深究的事物。对技术、成长、效率、认知、人生有着持续的好奇心和行动力。 坚信「飞轮效应」,相信每一次微小的积累,终将带来深远的改变。

评论

发布
暂无评论
大数据-174 Elasticsearch 查询 DSL 实战:match/match_phrase/query_string/multi_match 全解析_nosql_武子康_InfoQ写作社区