Kibana Query Language - KQL

原创
07/29 08:00
阅读数 118

导语



Kibana Query Language (KQL) 是一种使用自由文本搜索或基于字段的搜索过滤 Elasticsearch 数据的简单语法。KQL 仅用于过滤数据,并没有对数据进行排序或聚合的作用。


KQL 能够在你键入时建议字段名称、值和运算符。建议的性能由 Kibana 设置控制:


在上面的搜索框的右边,我们可以看到 KQL 字样。它表明当前的模式是 KQL 查询。


KQL 具有与 Lucene 查询语法不同的一组功能。KQL 能够查询嵌套字段和脚本字段。KQL 不支持正则表达式或模糊术语搜索。要使用传统的 Lucene 语法,请单击搜索框右边的 KQL,然后关闭 KQL。


有关 KQL 的一些介绍,在我的另外一篇文章 “Kibana: 如何使用 Search Bar” 中有所介绍。


准备数据


在今天的练习中,我将使用 Kibana 自带的索引来做展示:


这样我们就在 Elasticsearch 中创建了一个叫做 kibana_sample_data_logs 的索引。


Terms query


术语查询使用精确的搜索术语。空格分隔每个搜索词,并且只需要一个词来匹配文档。使用引号表示短语匹配(phrase match)。


要使用精确搜索词进行查询,请输入字段名称,后跟 :,然后输入以空格分隔的值:


如上所示。在 response 中只要匹配其中的任何一个 200,400,或者 503,那么搜索的答案都会显示出来。


对于文本字段,无论顺序如何,这都将匹配任何值:


要查询确切的短语(phrase),请在值周围使用引号:


KQL 不需要字段名称。如果未提供字段名称,则索引设置中的默认字段将匹配术语。要跨字段搜索:


Boolean queries


KQL 支持 or、and 和 not。默认情况下,and 的优先级高于 or。要覆盖默认优先级,请在括号中将运算符分组。这些运算符可以是大写或小写。


要匹配 response 为 200、或者地理位置目的地(geo.dest)为 CN. 或两者都满足的文档:

response: 200 or geo.dest: "CN"


要匹配 response 为 200 且 geo.dest 为 CN 的文档:

response: 200 and geo.dest: "CN"


从上面,我们可以看出来,查询的结果为290,明显比上次的查询结果少。


匹配 response 为 200 或 404 的文档:

response:(200 or 404)


要匹配 response 为 200 且 extension 为 php 或 css 的文档: 

response:200 and (extension:php or extension:css)


要匹配 response 为 200 且 extension 为 php 或 extension 为 css 且 response 为任何内容的文档。还记得我们之前说过的 and 的优先级比 or 要高:

response:200 and extension:php or extension:css


你可以理解上面的查询是这样的:

(response:200 and extension:php) or extension:css


匹配 response 不是 200 的文档:

not response:200


匹配 response 为 200 但 extension 不是 php 或 css 的文档:

response:200 and not (extension:php or extension:css)


要匹配包含术语列表的多值字段:

tags:(success and info and security)


Range queries


KQL 支持数字和日期类型的 >、>=、< 和 <=。

bytes > 1000 and (hour_of_day>10 and hour_of_day <14  )


Date range queries


通常,Kibana 的时间过滤器足以设置时间范围,但在某些情况下,你可能需要搜索日期。在引号中包含日期范围。


Exits queries


Exist 查询匹配包含任何字段值的文档,在本例中为响应:

response:*


存在由 Elasticsearch 定义,包括所有值,包括空文本。 


Wildcard queries


通配符查询可用于按术语前缀搜索或搜索多个字段。Kibana 的默认设置出于性能原因禁止使用前导通配符,但可以通过高级设置允许。


要匹配 machine.os 以 win 开头的文档,例如 “windows 7” 和 “windows 10”:

machine.os:win*


 匹配多个字段:

machine.os*: win* 10


 当你有字段的 text 和 keyword 版本时,此语法很方便。该查询检查 machine.os 和 machine.os.keyword 中的术语 win 10。


Nested field queries


查询嵌套字段的一个主要考虑因素是如何将嵌套查询的部分匹配到单个嵌套文档。你可以:

  • 仅将查询的部分匹配到单个嵌套文档。这是大多数用户在查询嵌套字段时想要的。

  • 将查询的部分匹配到不同的嵌套文档。这就是常规对象字段的工作方式。此查询通常不如匹配单个文档有用。


在以下文档中,items 是一个嵌套字段。嵌套字段中的每个文档都包含 name、stock 和 category。

{  "grocery_name": "Elastic Eats",  "items": [    {      "name": "banana",      "stock": "12",      "category": "fruit"    },    {      "name": "peach",      "stock": "10",      "category": "fruit"    },    {      "name": "carrot",      "stock": "9",      "category": "vegetable"    },    {      "name": "broccoli",      "stock": "5",      "category": "vegetable"    }  ]}


我们创建一个如下的 test 索引:

PUT test{  "mappings": {    "properties": {      "grocery_name": {        "type": "text"      },      "items": {        "type": "nested",        "properties": {          "category": {            "type": "text"          },          "name": {            "type": "text"          },          "stock": {            "type": "integer"          }        }      }    }  }}


我们创建如下的一个文档:

PUT test/_doc/1{  "grocery_name": "Elastic Eats",  "items": [    {      "name": "banana",      "stock": "12",      "category": "fruit"    },    {      "name": "peach",      "stock": "10",      "category": "fruit"    },    {      "name": "carrot",      "stock": "9",      "category": "vegetable"    },    {      "name": "broccoli",      "stock": "5",      "category": "vegetable"    }  ]}


我们为 test 索引创建一个叫做 test* 的索引模式。


匹配单个文档


要匹配库存超过 10 个香蕉的商店:

items:{ name:banana and stock > 10 }


items 是 nested path。花括号(嵌套组)内的所有内容都必须匹配单个嵌套文档。


 以下查询不返回任何匹配项,因为没有单个嵌套文档具有库存为 9 的香蕉。

items:{ name:banana and stock:9 }


匹配不同的文档


以下子查询位于单独的嵌套组中,可以匹配不同的嵌套文档:

items:{ name:banana } and items:{ stock:9 }


name:banana 匹配数组中的第一个文档,而 stock:9 匹配数组中的第三个文档。


匹配单个和不同的文档


要找到一家拥有 10 多个香蕉且同时备有蔬菜的商店:

items:{ name:banana and stock > 10 } and items:{ category:vegetable }


 第一个嵌套组(name:banana and stock > 10)必须匹配单个文档,但是 category:vegetables 子查询可以匹配不同的嵌套文档,因为它在一个单独的组中。


其他嵌套字段内的嵌套字段


KQL 支持其他嵌套字段中的嵌套字段——你必须指定完整路径。在本文档中,level1 和 level2 是嵌套字段:

{  "level1": [    {      "level2": [        {          "prop1": "foo",          "prop2": "bar"        },        {          "prop1": "baz",          "prop2": "qux"        }      ]    }  ]}


要匹配单个嵌套文档:

level1.level2:{ prop1:foo and prop2:bar }


参考:

【1】

https://www.elastic.co/guide/en/kibana/current/kuery-query.html


正文完



 作者:刘晓国

本文编辑:喝咖啡的猫



嗨,互动起来吧!

喜欢这篇文章么?

欢迎留下你想说的,留言 100% 精选哦!

Elastic 社区公众号长期征稿,如果您有 Elastic  技术的相关文章,也欢迎投稿至本公众号,一起进步! 投稿请添加微信:medcl123



招聘信息

Job board


社区招聘栏目是一个新的尝试,帮助社区的小伙伴找到心仪的职位,也帮助企业找到所需的人才,为伯乐和千里马牵线搭桥。有招聘需求的企业和正在求职的社区小伙伴,可以联系微信 medcl123 提交招聘需求和发布个人简历信息。


Elastic中文社区公众号 (elastic-cn)

为您汇集 Elastic 社区的最新动态、精选干货文章、精华讨论、文档资料、翻译与版本发布等。

喜欢本篇内容就请给我们点个[在看]吧




本文分享自微信公众号 - Elastic中文社区(elastic-cn)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部