沉梦听雨.头像

【搜索引擎】Lucene查询语法

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~2error, errors, terror, mirror
error~11error, errors
error~00error(等同 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-1h1 小时前
now-1d1 天前
now-7d7 天前
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~2

KQL vs Lucene 对比

特性KQLLucene
字段匹配field: valuefield: value
多值 ORfield: ("a", "b")field:(a OR b)
逻辑运算and / or / not(不区分大小写)AND / OR / NOT(必须大写)
范围查询field: [1 TO 10]field:[1 TO 10]
嵌套查询支持嵌套对象不支持
字段存在field: *_exists_:field(旧)/ field:*(新)
默认运算符OROR
可读性更高较低
适用场景Kibana 查询栏query_string DSL / 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"
    }
  }
}

常用参数

参数说明默认值
queryLucene 查询语句-
default_field未指定字段时的默认搜索字段*(所有字段)
default_operator默认运算符OR
allow_leading_wildcard是否允许 * 开头的通配符true
analyze_wildcard是否对通配符查询分词false
minimum_should_matchOR 条件最少匹配数1

示例

GET /_search
{
  "query": {
    "query_string": {
      "query": "(status:200 OR status:201) AND service:user-service",
      "default_operator": "AND"
    }
  },
  "size": 10,
  "sort": [
    { "@timestamp": "desc" }
  ]
}

学习参考

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/qq_54088234/article/details/170046286

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--