1. 每种查询语法的区别与优缺点
Query DSL
- 区别: JSON 格式的结构化查询,功能强大,支持复杂查询逻辑,适用于 Elasticsearch 的核心查询场景。
- 优点: 灵活,功能全面,支持全文搜索、精确匹配、聚合等;可组合多种查询类型。
- 缺点: 语法复杂,学习曲线较陡;JSON 格式对新手不友好。
SQL Query
- 区别: 使用标准 SQL 语法,适合熟悉关系型数据库的用户。
- 优点: 语法简单,易于上手;与传统 SQL 数据库兼容性高,适合快速查询。
- 缺点: 功能受限,无法完全发挥 Elasticsearch 的全文搜索和复杂查询能力。
EQL (Event Query Language)
- 区别: 专注于时间序列和事件数据,适合分析日志、事件流等场景。
- 优点: 针对事件序列分析优化,支持时间相关查询;语法直观。
- 缺点: 应用场景较窄,仅限事件数据;功能不如 Query DSL 全面。
Painless Scripting
- 区别: 基于脚本的查询,允许自定义逻辑,操作字段值或复杂条件。
- 优点: 高度灵活,可实现复杂计算或过滤逻辑。
- 缺点: 性能开销大,脚本错误可能导致查询失败;调试困难。
Kibana Console Query
- 区别: 通过 Kibana 的 REST API 风格执行查询,结合 HTTP 方法操作 Elasticsearch。
- 优点: 直观,适合调试和快速测试;与 Query DSL 无缝集成。
- 缺点: 依赖 Kibana 界面,手动输入 JSON 查询效率较低。
2. 带解释的查询示例
Query DSL
a. Match Query
{"query": {"match": {"name": "apple phone"}}
}
- 解释: 全文搜索
name
字段中包含 “apple” 或 “phone” 的文档。使用分词器匹配,适合模糊搜索。 - 场景: 搜索产品名称包含 “apple phone” 的商品。
b. Match with Fuzziness
{"query": {"match": {"name": {"query": "apple phone","fuzziness": "AUTO"}}}
}
- 解释: 允许模糊匹配,容忍拼写错误(如 “aple” 匹配 “apple”)。
fuzziness: AUTO
自动调整容错范围。 - 场景: 用户输入可能有误时,增强搜索容错。
c. Term Query
{"query": {"term": {"category": "electronics"}}
}
- 解释: 精确匹配
category
字段为 “electronics” 的文档,不分词。 - 场景: 查找特定类别的产品,如电子产品。
d. Terms Query
{"query": {"terms": {"category": ["electronics", "accessories"]}}
}
- 解释: 匹配
category
字段为 “electronics” 或 “accessories” 的文档。 - 场景: 筛选多个特定类别的产品。
e. Range Query
{"query": {"range": {"price": {"gte": 100,"lte": 500}}}
}
- 解释: 查找
price
字段在 100 到 500 之间的文档。 - 场景: 筛选价格区间内的产品。
f. Bool Query
{"query": {"bool": {"must": [{ "match": { "name": "phone" } },{ "range": { "price": { "lte": 1000 } } }],"filter": [{ "term": { "category": "electronics" } }]}}
}
- 解释: 组合查询,
must
要求name
包含 “phone” 且price
≤ 1000,filter
要求category
为 “electronics”。filter
不影响评分,性能更高。 - 场景: 复杂条件筛选,如电子产品中价格低于 1000 的手机。
g. Exists Query
{"query": {"exists": {"field": "description"}}
}
- 解释: 返回具有非空
description
字段的文档。 - 场景: 筛选有描述信息的产品。
h. Wildcard Query
{"query": {"wildcard": {"name": "app*"}}
}
- 解释: 匹配
name
字段以 “app” 开头的文档,*
表示任意字符。 - 场景: 搜索以 “app” 开头的产品名称。
i. Nested Query
{"query": {"nested": {"path": "comments","query": {"match": { "comments.text": "good" }}}}
}
- 解释: 查询嵌套字段
comments
中text
包含 “good” 的文档。处理嵌套对象关系。 - 场景: 搜索包含正面评论的产品。
SQL Query
a. Basic SELECT
SELECT name, price FROM products WHERE price > 100
- 解释: 返回
price
大于 100 的文档,仅显示name
和price
字段。 - 场景: 快速查看高价产品的基本信息。
b. With Conditions
SELECT * FROM products WHERE category = 'electronics' AND price BETWEEN 200 AND 500
- 解释: 筛选
category
为 “electronics” 且price
在 200-500 之间的所有字段。 - 场景: 查找特定类别和价格范围的产品。
c. Aggregation
SELECT category, AVG(price) FROM products GROUP BY category
- 解释: 按
category
分组,计算每组的平均price
。 - 场景: 分析各产品类别的平均价格。
EQL
a. Sequence Query
{"query": "sequence [event where event_type == 'login'] [event where event_type == 'logout' by user_id]"
}
- 解释: 查找按
user_id
关联的连续事件,先login
后logout
。 - 场景: 分析用户登录和登出行为序列。
b. Simple Event Query
{"query": "event where event_type == 'error' and severity > 3"
}
- 解释: 查找
event_type
为 “error” 且severity
大于 3 的事件。 - 场景: 筛选高严重性错误日志。
Painless Scripting
a. Field Calculation
{"query": {"script_score": {"query": { "match_all": {} },"script": {"source": "doc['price'].value * 0.9"}}}
}
- 解释: 对所有文档的
price
字段值乘以 0.9,影响搜索评分。 - 场景: 动态调整价格用于排序(如折扣计算)。
b. Filter with Script
{"query": {"bool": {"filter": {"script": {"script": {"source": "doc['price'].value > params.min_price","params": { "min_price": 100 }}}}}}
}
- 解释: 过滤
price
大于 100 的文档,使用参数化脚本。 - 场景: 动态设置价格过滤条件。
Kibana Console Query
a. Simple GET
GET products/_search
{"query": {"match": {"name": "phone"}}
}
- 解释: 通过 REST API 搜索
name
包含 “phone” 的文档。 - 场景: 在 Kibana 控制台快速测试查询。
b. Aggregation
GET products/_search
{"aggs": {"by_category": {"terms": { "field": "category" }}}
}
- 解释: 按
category
字段分组,统计每个类别的文档数。 - 场景: 分析产品类别分布。
注意
- 每个查询语法针对不同场景:Query DSL 适合复杂查询,SQL 适合快速上手,EQL 适合事件分析,Painless 适合自定义逻辑,Kibana 适合调试。
- 示例基于通用字段,实际使用需调整字段名和索引。
- 更多细节参考:https://www.elastic.co/docs/reference/query-languages/