ElasticSearch query_string 语法样例,收藏备用
众所周知,ElasticSearch 支持多种不同的检索语法,比如 DSL、SQL、EQL 等,其中 DSL 中的 query_string 极为灵活,甚至可以看做是和其他语法同等重要的一种语法。夜莺的日志监控就是支持的 query_string,但是大家查询日志更习惯的可能是 KQL,对 query_string 的方式略显陌生,所以这里给大家分享一些 query_string 的样例,供大家收藏备用。
快速摘要
query_string是 Elasticsearch DSL 查询中的一种字符串查询语法,适合在日志过滤条件里快速表达字段、关键字、范围和布尔组合。- 在夜莺日志监控的过滤条件里,通常只需要填写
title:(java AND intro)这类查询表达式,不需要填写完整 JSON。 - 本文用一个只有两条记录的
blog索引演示 match、match_phrase、wildcard、range、exists 和多条件组合。 - 生产环境使用时要注意字段类型、分词方式、特殊字符转义和时间范围边界。
数据集
我这个数据集很简单,只有两条数据,使用 SQL 方式查询,展示为 txt 方式,便于查看:
POST /_sql?format=txt
{
"query": "select * from blog"
}
从上面的 SQL 可以看出,我的索引叫 blog,查询结果如下:
author | content | published_date | title
---------------+----------------------+------------------------+-----------------------------
qin |java language is great|2023-01-01T00:00:00.000Z|first blog: java intro
xiaohui |prometheus is great |2023-01-02T00:00:00.000Z|second blog: prometheus intro
后面的示例都基于这个数据集,重点不是演示复杂查询,而是说明 query_string 在常见日志过滤和告警条件里的写法。
query_string 样例
| 场景 | query_string 写法 | 作用 |
|---|---|---|
| 字段包含关键词 | title:java intro |
查询 title 中包含相关词的文档 |
| 短语精确匹配 | title:"java intro" |
查询 title 中包含完整短语的文档 |
| 通配符匹配 | title:sec* |
查询以 sec 开头的 title |
| 时间范围 | published_date:>=2023-01-01 |
查询指定时间之后的文档 |
| 字段存在 | _exists_:title |
查询存在 title 字段的文档 |
| 多条件组合 | _exists_:title AND content:prometheus AND published_date:>2023 |
同时满足多个条件 |
1. 类似 match 的查询
GET blog/_search
{
"query": {
"query_string": {
"query": "title:java intro"
}
}
}
上面的查询会返回两条记录。因为两条记录的 title 字段都包含了 intro 这个关键字。如果只想返回第一条记录,中间就要加上 AND,即:title:java AND intro,当然,加上括号可能更清晰:title:(java AND intro)。
夜莺的过滤条件里,只写 title:(java AND intro) 就可以了,不要把整个 JSON 都写进去。
2. 类似 match_phrase 的查询
GET blog/_search
{
"query": {
"query_string": {
"query": "title:\"java intro\""
}
}
}
在 java intro 外侧加上双引号,表示要精确匹配这个短语,这个查询只会返回第一条记录。
3. 类似 wildcard 的查询
GET blog/_search
{
"query": {
"query_string": {
"query": "title:sec*"
}
}
}
上面的查询会返回第二条记录,因为第二条记录的 title 字段以 sec 开头。注意上面的 sec 后面的那个 *,表示 0 个或多个任意字符。
4. 类似 range 的查询
GET blog/_search
{
"query": {
"query_string": {
"query": "published_date:>=2023-01-01"
}
}
}
上面的查询会返回两条记录,因为两条记录的 published_date 字段都大于等于 2023-01-01。如果只想返回第一条记录,可以这么写:published_date:>=2023-01-01 AND <2023-01-02。
还有另一种写法,published_date:[2023-01-01 TO 2023-01-02],这个写法会把两条记录都返回。
5. exists 查询
GET blog/_search
{
"query": {
"query_string": {
"query": "_exists_:title"
}
}
}
返回两条记录,因为两条记录的 title 字段都存在。
6. 多个字段同时满足条件
GET blog/_search
{
"query": {
"query_string": {
"query": "_exists_:title AND content:prometheus AND published_date:>2023"
}
}
}
上例是三个查询条件拼在一起,会返回第二条记录。
总结
上面的几个样例帮你入门,找找感觉。更详细的 query_string 语法可以参考 ElasticSearch 官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html。
FAQ
Q1:夜莺日志监控里应该写完整 JSON 吗?
A:不需要。夜莺过滤条件里写 query_string 表达式本身即可,例如 title:(java AND intro)。
Q2:title:java intro 为什么会返回两条记录?
A:因为 intro 没有限定字段,两条记录的 title 都包含 intro。如果希望 java 和 intro 都限定在 title 字段里,可以写成 title:(java AND intro)。
Q3:什么时候用短语查询?
A:当你希望关键词按固定顺序、作为完整短语匹配时,用双引号,例如 title:"java intro"。