Lucene 查询语法
Lucene 查询语法是 Elasticsearch 的底层查询语言,Kibana 的 Lucene 模式和 ES 的query_string查询都基于此语法。
语法概览
Lucene 查询语法分为两大类:
| 查询类型 | 语法 | 说明 |
|---|---|---|
| Term 查询 | field: value | 精准匹配,不分词 |
| Phrase 查询 | field: "hello world" | 短语匹配,按完整顺序匹配 |
| 通配符查询 | field: hel*o | *匹配任意字符,?匹配单个字符 |
| 模糊查询 | field: hello~ | 基于编辑距离的模糊匹配 |
| 范围查询 | field:[1 TO 10] | 数值/日期范围 |
| 布尔查询 | AND/OR/NOT | 逻辑组合 |
| 正则查询 | field:/regex/ | 正则表达式匹配 |
基础语法
Term 查询(词条匹配)
不分词,精确匹配整个字段值:
status: 200 service: user-service注意:Term 查询不会对搜索词分词。
service: user-service不会匹配user或service。
Phrase 查询(短语匹配)
用双引号包裹,按完整顺序匹配:
message: "connection timeout"- 匹配:
"connection timeout occurred" - 不匹配:
"timeout connection"(顺序不对) - 不匹配:
"connection reset timeout"(中间有其他词)
短语邻近度
~后跟数字,表示允许的词间距:
message: "connection timeout"~3表示connection和timeout之间最多允许 3 个词,匹配如"connection was reset due to timeout"。
通配符查询
| 通配符 | 含义 | 示例 |
|---|---|---|
* | 匹配 0 个或多个字符 | uri: *app* |
? | 匹配 1 个字符 | uri: my-service-?edia |
# 匹配以 app 开头的 URL uri: app* # 匹配任意位置包含 app 的 URL uri: *app* # 匹配单个字符差异 service: user-?ervice性能提示:以
*开头的通配符查询性能较差,ES 需要扫描所有词项。尽量避免*xxx形式。
模糊查询
~表示基于**编辑距离(Levenshtein Distance)**的模糊匹配:
# 默认允许 2 个字符差异 message: error~ # 指定编辑距离为 1 message: error~1| 查询 | 编辑距离 | 匹配示例 |
|---|---|---|
error~ | 2 | error, errors, terror, mirror |
error~1 | 1 | error, errors |
error~0 | 0 | error(等同 Term 查询) |
编辑距离:将一个词变成另一个词所需的最少操作数(插入、删除、替换)。
范围查询
闭区间[ ]
# 数值范围(包含边界) response.time:[100 TO 500] # 日期范围 @timestamp:["2026-07-31T00:00:00" TO "2026-07-31T23:59:59"]开区间{ }
# 不包含边界 response.time:{100 TO 500} # 混合使用 response.time:[100 TO 500}开放范围
# 大于等于 100 response.time:[100 TO *] # 小于 500 response.time:[* TO 500]日期数学
ES 支持日期数学表达式:
@timestamp:["now-1h" TO "now"] @timestamp:["now-7d" TO "now"] @timestamp:["now/d" TO "now"] # 今天 0 点到现在 @timestamp:["now-1d/d" TO "now-1d/d"] # 昨天 0 点到昨天结束| 表达式 | 含义 |
|---|---|
now | 当前时间 |
now-1h | 1 小时前 |
now-1d | 1 天前 |
now-7d | 7 天前 |
now/d | 今天 0 点(向下取整到天) |
now+1d/d | 明天 0 点 |
布尔查询
运算符
| 运算符 | 说明 | 示例 |
|---|---|---|
AND | 同时满足 | status:200 AND service:user |
OR | 满足其一 | status:200 OR status:201 |
NOT | 排除 | status:200 NOT service:user |
+ | 必须包含 | +status:200 +service:user |
- | 必须排除 | +status:200 -service:user |
注意:Lucene 中
AND、OR、NOT必须大写,小写会被当作普通词项。
组合查询
# 括号控制优先级 (status:200 OR status:201) AND service:user-service # + 和 - 简写 +status:200 -service:order-service默认运算符
未指定运算符时,默认为OR:
# 以下两种写法等价 status:200 status:201 status:200 OR status:201可通过 ES 的default_operator参数修改为AND。
字段存在性
# 字段存在(有值) _exists_:uri # 字段不存在 _missing_:uri注意:ES 6.x+ 中
_exists_和_missing_已废弃,改用:# ES 6.x+ 写法 uri:* # 字段存在 NOT uri:* # 字段不存在
正则查询
用/包裹正则表达式:
# 匹配以 myapp 开头的服务名 service:/myapp-.*/ # 匹配数字结尾 uri:/.*[0-9]+$/限制:Lucene 正则不支持
^和$锚定符,默认全匹配。不支持反向引用和非贪婪量词。
转义特殊字符
以下字符在 Lucene 中有特殊含义,需用\转义:
+ - && || ! ( ) { } [ ] ^ " ~ * ? : \ /示例:
# 转义 URL 中的特殊字符 uri: "https\:\/\/example\.com\/api" # 转义括号 message: "error\(timeout\)"分词与匹配
text 字段 vs keyword 字段
| 字段类型 | 查询行为 | 示例 |
|---|---|---|
text | 搜索词会被分词,分别匹配 | message: connection timeout匹配包含connection或timeout的文档 |
keyword | 搜索词不分词,整体匹配 | uri.keyword: "http://example.com"精准匹配完整 URL |
分词器影响
text字段经过分词器处理后,查询时也会分词:
# 假设 message 是 text 类型,内容为 "Connection Timeout Error" message: "connection timeout" # 分词后匹配 "connection" 和 "timeout",能命中 message: "Connection Timeout" # 大小写不敏感(取决于分词器),能命中 message: "connectiontimeout" # 不会被分词为两个词,不命中完整示例
示例一:查找错误日志
# 查找 500 错误且包含 timeout 的日志 status:500 AND message:*timeout* # 查找非 200 的响应 NOT status:200 # 查找 4xx 或 5xx 错误 status:[400 TO 499] OR status:[500 TO 599]示例二:按时间范围和服务名查询
# 查找最近 1 小时 user-service 的日志 @timestamp:["now-1h" TO "now"] AND service:user-service示例三:排除特定路径
# 查找所有日志但排除健康检查 NOT uri:*health*示例四:多字段组合查询
# user-service 的 500 错误,排除 /api/health 路径 +service:user-service +status:500 -uri:*health*示例五:模糊匹配 + 范围
# 响应时间大于 500ms 且消息类似 "timeout" response.time:[500 TO *] AND message:timeout~2KQL vs Lucene 对比
| 特性 | KQL | Lucene |
|---|---|---|
| 字段匹配 | field: value | field: value |
| 多值 OR | field: ("a", "b") | field:(a OR b) |
| 逻辑运算 | and/or/not(不区分大小写) | AND/OR/NOT(必须大写) |
| 范围查询 | field: [1 TO 10] | field:[1 TO 10] |
| 嵌套查询 | 支持嵌套对象 | 不支持 |
| 字段存在 | field: * | _exists_:field(旧)/field:*(新) |
| 默认运算符 | OR | OR |
| 可读性 | 更高 | 较低 |
| 适用场景 | Kibana 查询栏 | query_stringDSL / Kibana Lucene 模式 |
建议:在 Kibana 中优先使用 KQL,语法更友好;在 ES DSL 的
query_string中使用 Lucene 语法。
在 ES DSL 中使用
Lucene 语法通过query_string在 ES DSL 中使用:
GET/_search{"query":{"query_string":{"query":"status:200 AND service:user-service","default_field":"message"}}}常用参数
| 参数 | 说明 | 默认值 |
|---|---|---|
query | Lucene 查询语句 | - |
default_field | 未指定字段时的默认搜索字段 | *(所有字段) |
default_operator | 默认运算符 | OR |
allow_leading_wildcard | 是否允许*开头的通配符 | true |
analyze_wildcard | 是否对通配符查询分词 | false |
minimum_should_match | OR 条件最少匹配数 | 1 |
示例
GET/_search{"query":{"query_string":{"query":"(status:200 OR status:201) AND service:user-service","default_operator":"AND"}},"size":10,"sort":[{"@timestamp":"desc"}]}学习参考
- Lucene Query Parser 语法
- ES query_string 文档
- ES 日期数学