Kibana 查询语法 KQL

FreeGuideOnline 14阅读 2026-07-13

什么是 Kibana 查询语言 (KQL)

Kibana 查询语言(Kibana Query Language,简称 KQL)是一套专为 Kibana 设计的简化查询语法,用于在 DiscoverDashboardVisualize 等应用中快速过滤、搜索 Elasticsearch 数据。KQL 的定位是“类自然语言”,让你无需掌握复杂的 Lucene 或 Elasticsearch Query DSL,就能通过直观的表达式完成绝大多数日常分析任务。

与旧版 Lucene 语法相比,KQL 的主要优势包括:

  • 自动识别字段:输入字段名后按冒号,系统会提示可选值。
  • 更宽松的引号规则:多数字符串无需加引号,除非包含特殊字符或空格。
  • 简化的逻辑运算andornot 直接书写,且支持括号组合。
  • 内置函数:提供如 exists* 等简洁的字段存在或匹配判断。

启用 KQL

在 Kibana 界面的搜索框左侧,确认语言切换器处于 KQL 状态。若显示为“Lucene”,点击即可切换。KQL 是当前版本的默认查询语言。

基础语法规则

KQL 表达式由 字段查询自由文本查询 组成,二者可以混合使用,并通过逻辑运算符连接。

自由文本查询

最简单的用法是直接输入一个或多个单词,Kibana 会在所有已索引的字段中搜索这些词。多个单词之间默认为 or 关系,即只要文档的任一字段包含任意一个单词就会被命中。

error timeout

等同于在所有字段中查找包含 “error” 或 “timeout” 的文档。

字段查询

针对特定字段进行精确或模糊匹配,语法为:

字段名:值

示例:

status:200

查找 status 字段值为 200 的文档。

如果字段名包含特殊字符(如 @.),可以不用引号直接书写,但建议使用反引号包裹避免歧义:

`@timestamp`:"2023-01-01T00:00:00Z"

字符串与短语匹配

无引号字符串

字符串中若不包含空格或特殊字符,可以直接书写:

message:success

带引号的短语

当值包含空格或需要精确匹配整个短语时,使用双引号:

message:"internal server error"

通配符

KQL 支持两种通配符:

  • * 匹配零个或多个字符。
  • ? 匹配单个字符。

通配符不能作为第一个字符使用(即不能以 *? 开头),否则会触发性能限制错误。

正确示例:

user:admin*
status:40?

分别匹配 user 字段以 “admin” 开头的值,以及 status 字段为 “400” 到 “409” 之间值(如 401、403 等)。

数字、日期与布尔值查询

数字查询

直接书写数字即可,无需引号:

bytes:>1024

表示 bytes 字段大于 1024。

日期查询

日期值需要使用双引号,并且格式需符合 ISO 8601。支持数学表达式简写:

@timestamp > "2024-01-01"
@timestamp < "now-1d/d"

后者表示时间早于一天前的午夜。

布尔值查询

直接使用 truefalse(不区分大小写):

is_bot:true

比较运算符

KQL 支持对数值、日期和关键字类型字段使用比较运算符:

  • > 大于
  • < 小于
  • >= 大于等于
  • <= 小于等于

示例:

bytes >= 2048
response_time < 500

逻辑运算符

KQL 使用英文单词 andornot(大小写均可)来组合查询条件,并支持括号 () 显式控制优先级。如果不使用括号,not 的优先级最高,and 次之,or 最低。

与(and)

status:200 and extension:php

返回 status 为 200 且 extension 为 php 的文档。

或(or)

status:400 or status:500

非(not)

not status:200

排除 status 为 200 的文档。not 也可以放在字段查询前,但更推荐放在最前面。

组合示例

(status:400 or status:500) and not user:"John Doe"

范围查询

除了比较运算符,KQL 还提供闭区间和开区间的范围查询,适用于数字、日期及 IP 地址字段。

  • 闭区间 [ ]:包含边界值
    bytes:[1000 TO 2000]
    
  • 开区间 { }:不包含边界值
    bytes:{1000 TO 2000}
    
  • 混合区间:一边包含、一边不包含
    bytes:[1000 TO 2000}
    

范围查询中 TO 必须大写,且值两侧不用加引号,除非值本身包含空格(如日期)。例如日期范围:

@timestamp:["2024-06-01" TO "2024-06-30"]

存在性查询

如果只关心某个字段是否存在于文档中,可以使用 * 操作符,即字段存在且不为空。

error_message:*

返回所有含有 error_message 字段的文档。

若字段值为空或不存在,可以用 not 结合:

not error_message:*

注意:KQL 没有类似 exists 的显式函数(新版 ES 有 exists 查询,但在 KQL 中直接使用 * 即可)。

特殊字符的转义

当搜索的值中包含 KQL 保留字符时,需要使用反斜杠 \ 进行转义。也需要转义的字符包括:

( ) " : * \ ? [ ] { }

示例:查找 user_agent 中包含字面量 "Mozilla/5.0 (compatible" 的文档:

user_agent:"Mozilla/5.0 \(compatible"

注意:双引号内部的 \" 也需要转义。

嵌套字段查询

对于 Elasticsearch 中的嵌套对象(nested 类型),正常 KQL 语法无法直接访问内层属性。KQL 不支持原生的嵌套查询,但可以通过切换到 Lucene 语法或使用 ES|QL 来处理。在 KQL 环境中,若字段是 object 类型(非 nested),可以直接用点号访问:

user.name:"John"

如果文档中 user 是 object 类型,上述语句有效。

多值字段匹配

如果一个字段包含数组(如 tags: ["api", "production"]),KQL 的等于匹配会返回任意一个元素满足条件的文档。

tags:api

只要 tags 数组中存在 “api” 值即可命中。

模糊查询与正则表达式

KQL 不直接支持模糊查询(如 ~)或正则表达式。这类高级匹配需要切换到 Lucene 语法或使用 Elasticsearch 的 Query DSL。对于日常分析,通配符已能满足大部分需求。

实战示例

场景 KQL 语句
查找今日所有错误日志 level:ERROR and @timestamp > "now/d"
排除来自测试用户的请求 not user:"test_user"
响应时间在 200-500ms 之间,且状态码为 200 response_time:[200 TO 500] and status:200
搜索路径中包含 “admin” 的请求 request_path:*admin*
找出所有来自 Chrome 浏览器的请求 user_agent:"Chrome" (或用通配 user_agent:*Chrome*

KQL 的局限性

  • 不支持正则表达式和模糊搜索(Levenshtein 距离)。
  • 不能在单个 or 表达式中对不同字段使用相同的值精简写法(如 status:(200 or 400) 无效),需分开书写。
  • 对嵌套类型的原生支持较弱。
  • 查询字符串前后的空格会被自动裁剪,但引号内的空格保留。

当遇到这些场景时,可临时切换至 Lucene 语法或使用 ES|QL 的管道式查询。

最佳实践

  1. 善用 Kibana 的字段提示:键入字段名时自动补全字段,输入值时会显示可选值列表,极大提升效率。
  2. 先用自由文本快速探索,再精确字段限定:先看看数据长什么样,然后逐步添加 message:error 等字段约束。
  3. 处理日志或文本时,优先使用通配符代替精确短语:除非你确信日志格式一成不变。
  4. 保存常用搜索为“Saved Query”:点击搜索栏右侧的软盘图标,方便重复使用。
  5. 密切关注时间范围:KQL 本身不限制时间,但你选择的 time picker 范围会隐式地过滤结果,务必确认右上角的时间窗口。

掌握以上 KQL 语法,你就能高效地在 Kibana 中探索、过滤和诊断海量数据了。