写点什么

大数据 -175 Elasticsearch Term 精确查询与 Bool 组合实战:range/regexp/fuzzy 全示例

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

    阅读完需:约 13 分钟

大数据-175 Elasticsearch Term 精确查询与 Bool 组合实战:range/regexp/fuzzy 全示例

TL;DR

  • 场景:业务既有精确匹配(价格、ID、时间),又有容错需求(前缀、模糊、错别字)。

  • 结论:用 term-level queries 处理结构化精确条件,再用 bool 组合 must/filter/should/must_not。

  • 产出:给出从建索引、写入数据到 term/terms/range/exists/prefix/regexp/fuzzy/ids/bool 全流程 DSL 示例。


版本矩阵



可以使用 term-level queries 根据结构化数据中的精确值查找文档。结构化数据的值包括日期范围、IP 地址、价格或者产品 ID。与全文查询不同,term-level queries 不分析搜索词。相反,词条与存储在字段级别中的术语完全匹配。

初始索引

新建一个 book 一个索引:


# 新建book索引PUT /book{  "settings": {},  "mappings" : {    "properties" : {      "description" : {        "type" : "text",        "analyzer" : "ik_max_word"      },      "name" : {        "type" : "text",        "analyzer" : "ik_max_word"      },      "price" : {        "type" : "float"      },      "timestamp" : {        "type" : "date",        "format" : "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"      }    }  }}
复制代码


执行的结果如下图所示:


写入数据

生成几条数据用作我们后续的测试:


# 新增数据1PUT /book/_doc/1{  "name": "lucene",  "description": "Lucene Core is a Java library providing powerful indexing and search features, as well as spellchecking, hit highlighting and advanced analysis/tokenization capabilities. The PyLucene sub project provides Python bindings for Lucene Core. ",  "price":100.45,  "timestamp":"2020-08-21 19:11:35"}
# 新增数据2PUT /book/_doc/2{ "name": "solr", "description": "Solr is highly scalable, providing fully fault tolerant distributed indexing, search and analytics. It exposes Lucenes features through easy to use JSON/HTTP interfaces or native clients for Java and other languages.", "price":320.45, "timestamp":"2020-07-21 17:11:35"}
# 新增数据3PUT /book/_doc/3{ "name": "Hadoop", "description": "The Apache Hadoop software library is a framework that allows for the distributed processing of large data sets across clusters of computers using simple programming models.", "price":620.45, "timestamp":"2020-08-22 19:18:35"}
# 新增数据4PUT /book/_doc/4{ "name": "ElasticSearch", "description": "Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。", "price":999.99, "timestamp":"2020-08-15 10:11:35"}
复制代码


执行的结果如下图所示:


词条搜索(term query)

term 查询用于查询指定字段包含某个词项的文档


# term是精确检索 多一个少一个都不行POST /book/_search{  "query": {    "term" : {       "name" : "solr"     }  }}
复制代码


执行的结果如下图所示:


词条集合搜索(terms query)

terms 查询用于查询指定字段包含某些词项的文档


# 要有检索内容的name中有solr、elasticsearch,多个条件POST /book/_search{  "query": {    "terms" : {       "name" : ["solr", "elasticsearch"]    }  }}
复制代码


执行的结果如下图所示:


范围搜索(range query)

  • gte 大于等于

  • gt 大于

  • lte 小于等于

  • lt 小于

  • boost 查询权重 在多条件查询时,可以手动控制每个条件的比重


# 范围检索 可以加权POST /book/_search{  "query": {    "range" : {      "price" : {        "gte" : 10,        "lte" : 200,        "boost" : 2.0      }    }  }}
复制代码


执行结果如下图所示:



继续执行:


# 范围检索 也可以指定格式POST /book/_search{  "query": {    "range" : {      "timestamp" : {        "gte": "18/08/2020",        "lte": "2021",        "format": "dd/MM/yyyy||yyyy"      }    }  }}
复制代码


执行结果如下图所示:


不为空搜索(exists query)

查询指定字段不为空的文档,相当于 SQL 中的 column is not null


# 不为空检索POST /book/_search{  "query": {    "exists" : { "field" : "price" }  }}
复制代码


执行结果如下图所示:


词项前缀搜索(prefix query)

# 检索以xx开头的数据POST /book/_search{  "query": {    "prefix" : {       "name" : "so"     }  }}
复制代码


执行结果如下图所示:


正则搜索(regexp query)

regexp 允许使用正则表达式进行 term 查询,注意 regexp 如果使用不正确,会给服务器带来很严重的性能压力,比如*开头的查询,将会匹配所有倒排索引中的关键字,这几乎是全表扫描,因此如果可以的话,最好使用正则前,加上匹配的前缀。


# 正则匹配POST /book/_search{  "query": {    "regexp":{      "name": "s.*"    }  }}
复制代码


执行的结果如下图所示:



这里也可以加入 boost 值来控制:


# 正则匹配 boost额外加权POST /book/_search{  "query": {    "regexp":{      "name":{        "value":"s.*",        "boost":1.2      }    }  }}
复制代码


执行结果如下图所示:


模糊搜索(fuzzy query)

# fuzzy 可以搜索到结果 solrPOST /book/_search{  "query": {    "fuzzy" : {       "name" : "sol"     }  }}
# 搜索不到结果 匹配不到 因为匹配字母数不够POST /book/_search{ "query": { "fuzzy" : { "name" : "so" } }}
# 通过 fuzziness 设置匹配字母的数量# 设置2个就可以从 so匹配到solr了POST /book/_search{ "query": { "fuzzy" : { "name" : { "value": "so", "fuzziness": 2 } } }}
复制代码


执行结果如下图 1 所示:



执行结果图 2 如下图所示:



继续准备执行:


# 写错字母顺序也可以匹配到(默认错1个)POST /book/_search{  "query": {    "fuzzy" : {      "name" : {        "value": "sorl"      }    }  }}
# 写错字母顺序多了匹配不到(超过了1个)POST /book/_search{ "query": { "fuzzy" : { "name" : { "value": "rlso" } } }}
# 通过fuzziness 设置错误的字母数量POST /book/_search{ "query": { "fuzzy": { "name": { "value": "osrl", "fuzziness":2 } } }}
复制代码


运行结果图 1 如下图所示:



运行结果图 2 如下图所示:


ids 搜索(id 集合查询)

# 根据ID查询POST /book/_search{  "query": {    "ids" : {      "values" : ["1", "3"]    }  }}
复制代码


执行的结果如下图所示:


复合搜索(compound query)

布尔搜索(bool query)

bool 查询操作来组合查询子句为一个查询,可用关键字:


  • must 必须满足

  • filter 必须满足,对集合包含/排除进行简单检查,速度非常快,不参与也不影响评分结果

  • should 或关系

  • must_not 必须不满足,在 filter 上下文中执行,不参与、不影响评分


假设我们有一个需求是:


  • description 中必须有 Java

  • price 必须满足大于 100 小于 1000

  • name 字段可以是 lucene 或者 solr 的一种即可

  • 时间满足某个时间节点


那么对应的 DSL 如下:


# 根据业务条件 编写的DSLPOST /book/_search{  "query": {    "bool": {      "filter": {        "match": {           "description": "java"         }      },      "must": [        {          "range": {            "price": {              "gte": 100,              "lte": 1000            }          }        },        {          "bool": {            "should": [              {                "term": {                  "name": "lucene"                }              },              {                "term": {                  "name": "solr"                }              }            ]          }        }      ],      "must_not": [        {          "range": {            "timestamp": {              "gte": "18/08/2020",              "lte": "2021",              "format": "dd/MM/yyyy||yyyy"            }          }        }      ]    }  }}
复制代码


执行结果如下图所示:


错误速查

其他系列

🚀 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 案例 详解🔗 大数据模块直达链接

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

武子康

关注

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

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

评论

发布
暂无评论
大数据-175 Elasticsearch Term 精确查询与 Bool 组合实战:range/regexp/fuzzy 全示例_nosql_武子康_InfoQ写作社区