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)
# 范围检索 可以加权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 查询操作来组合查询子句为一个查询,可用关键字:
假设我们有一个需求是:
那么对应的 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 案例 详解🔗 大数据模块直达链接
评论