Elasticsearch DSL 提供了极其丰富的查询功能,从简单的全文搜索到复杂的地理空间查询、嵌套文档查询和聚合分析。DSL 查询的基本结构包含以下几个主要部分:
{
"query": { ... }, // 查询条件(核心部分)
"aggs": { ... }, // 聚合分析
"sort": [ ... ], // 排序规则
"from": 0, // 分页起始位置
"size": 10, // 返回结果数量
"_source": { ... }, // 返回字段控制
"script_fields": { ... }, // 脚本字段
"highlight": { ... }, // 高亮显示
"explain": true, // 是否返回评分解释
"timeout": "10s" // 超时设置
}
Elasticsearch 的 DSL 查询语言提供了丰富的查询类型,可以满足各种搜索需求。query 查询主要分为以下几大类:
用于在文本字段上执行全文搜索,会对查询字符串进行分析处理。
{
"query": {
"match": {
"content": {
"query": "Elasticsearch tutorial",
"operator": "and", // 必须包含所有词项
"minimum_should_match": "75%", // 至少匹配75%的词项
"fuzziness": "AUTO", // 自动模糊匹配
"analyzer": "standard"
}
}
}
}
{
"query": {
"match_phrase": {
"title": {
"query": "quick brown fox",
"slop": 2, // 允许词项间最多间隔2个词
"analyzer": "english"
}
}
}
}
{
"query": {
"match_phrase_prefix": {
"title": {
"query": "Elast sear",
"max_expansions": 10, // 最多扩展10个前缀匹配项
"slop": 1
}
}
}
}
{
"query": {
"multi_match": {
"query": "Elasticsearch",
"fields": ["title^3", "content", "abstract^2"], // 字段权重设置
"type": "best_fields", // 最佳匹配字段得分
"tie_breaker": 0.3 // 其他匹配字段得分权重
}
}
}
{
"query": {
"query_string": {
"default_field": "content",
"query": "(Elasticsearch AND tutorial) OR (Kibana AND guide)",
"default_operator": "OR",
"allow_leading_wildcard": false,
"fuzziness": "AUTO"
}
}
}
field:value
指定字段搜索AND/OR/NOT
逻辑操作+
必须包含 -
必须不包含*
通配符~
模糊搜索[TO]
范围搜索{
"query": {
"simple_query_string": {
"query": "Elasticsearch +tutorial -beginner",
"fields": ["title", "content"],
"default_operator": "and",
"analyze_wildcard": true
}
}
}
{
"query": {
"term": {
"status": {
"value": "published",
"boost": 1.5 // 权重提升
}
}
}
}
{
"query": {
"terms": {
"tags": ["java", "search", "database"],
"boost": 2.0
}
}
}
{
"query": {
"range": {
"price": {
"gte": 100,
"lt": 1000,
"boost": 2.0,
"format": "yyyy-MM-dd" // 日期格式
}
}
}
}
{
"query": {
"exists": {
"field": "description"
}
}
}
{
"query": {
"prefix": {
"user.id": {
"value": "ki",
"rewrite": "constant_score" // 重写方法
}
}
}
}
{
"query": {
"wildcard": {
"user.id": {
"value": "k*y",
"boost": 1.0,
"rewrite": "scoring_boolean"
}
}
}
}
{
"query": {
"regexp": {
"user.id": {
"value": "k.*y",
"flags": "ALL",
"max_determinized_states": 10000
}
}
}
}
{
"query": {
"fuzzy": {
"title": {
"value": "Elastcsearch",
"fuzziness": "2", // 允许2个字符的差异
"prefix_length": 3 // 前3个字符必须精确匹配
}
}
}
}
bool 查询
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Elasticsearch" } },
{ "range": { "date": { "gte": "2023-01-01" } } }
],
"should": [
{ "match": { "content": "tutorial" } },
{ "term": { "category": "technology" } }
],
"must_not": [
{ "term": { "status": "archived" } }
],
"filter": [
{ "term": { "language": "english" } }
],
"minimum_should_match": 1,
"boost": 1.0
}
}
}
子句 | 描述 | 影响评分 | 使用场景 |
---|---|---|---|
must | 必须匹配 | 是 | 主要查询条件 |
should | 应该匹配 | 是 | 次要条件或增强相关性 |
must_not | 必须不匹配 | 否 | 排除条件 |
filter | 必须匹配 | 否 | 过滤条件 |
boosting 查询
{
"query": {
"boosting": {
"positive": {
"match": { "content": "apple" }
},
"negative": {
"match": { "content": "pie tart fruit" }
},
"negative_boost": 0.5,
"boost": 1.0
}
}
}
constant_score 查询
{
"query": {
"constant_score": {
"filter": {
"term": { "status": "active" }
},
"boost": 1.2
}
}
}
dis_max 查询
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "Elasticsearch" } },
{ "match": { "content": "Elasticsearch" } },
{ "match": { "abstract": "Elasticsearch" } }
],
"tie_breaker": 0.7,
"boost": 1.2
}
}
}
{
"query": {
"geo_distance": {
"distance": "10km",
"distance_type": "arc",
"location": {
"lat": 40.715,
"lon": -73.988
},
"validation_method": "STRICT"
}
}
}
{
"query": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 40.73,
"lon": -74.1
},
"bottom_right": {
"lat": 40.01,
"lon": -71.12
}
},
"validation_method": "COERCE"
}
}
}
{
"query": {
"geo_polygon": {
"location": {
"points": [
{ "lat": 40.73, "lon": -74.1 },
{ "lat": 40.01, "lon": -71.12 },
{ "lat": 50.56, "lon": -90.58 }
]
},
"validation_method": "IGNORE_MALFORMED"
}
}
}
{
"query": {
"more_like_this": {
"fields": ["title", "content"],
"like": [
{
"_index": "articles",
"_id": "1"
},
{
"_index": "articles",
"_id": "2"
}
],
"min_term_freq": 1,
"max_query_terms": 25,
"min_doc_freq": 2
}
}
}
{
"query": {
"script": {
"script": {
"source": """
double price = doc['price'].value;
double discount = params.discount;
return price * (1 - discount) > params.min_price;
""",
"params": {
"discount": 0.1,
"min_price": 50
}
}
}
}
}
{
"query": {
"pinned": {
"ids": ["1", "2", "3"],
"organic": {
"match": {
"description": "Elasticsearch"
}
}
}
}
}
{
"query": {
"nested": {
"path": "comments",
"query": {
"bool": {
"must": [
{ "match": { "comments.author": "John" } },
{ "range": { "comments.date": { "gte": "2023-01-01" } } }
]
}
},
"score_mode": "max",
"inner_hits": {
"size": 5,
"name": "latest_comments"
}
}
}
}
{
"query": {
"has_child": {
"type": "comment",
"score_mode": "sum",
"min_children": 2,
"max_children": 10,
"query": {
"match": { "content": "great" }
},
"inner_hits": {}
}
}
}
{
"query": {
"has_parent": {
"parent_type": "blog",
"score": true,
"query": {
"term": { "category": "technology" }
},
"inner_hits": {
"name": "parent_blog"
}
}
}
}
Elasticsearch 的聚合分析功能提供了强大的数据统计和分析能力,能够对数据进行分组、统计和计算各种指标。聚合操作可以嵌套使用,构建复杂的数据分析管道。
{
"aggs": { // 也可以使用"aggregations"
"agg_name": { // 自定义聚合名称
"agg_type": { // 聚合类型
"agg_body": ... // 聚合体
}
}
}
}
基本指标聚合
{
"aggs": {
"avg_price": {
"avg": { "field": "price" }
}
}
}
{
"aggs": {
"total_sales": {
"sum": { "field": "sales" }
}
}
}
{
"aggs": {
"max_age": {
"max": { "field": "age" }
}
}
}
{
"aggs": {
"price_stats": {
"stats": { "field": "price" }
}
}
}
{
"aggs": {
"price_extended_stats": {
"extended_stats": { "field": "price" }
}
}
}
{
"aggs": {
"unique_users": {
"cardinality": { "field": "user_id" }
}
}
}
高级指标聚合
{
"aggs": {
"load_time_percentiles": {
"percentiles": {
"field": "load_time",
"percents": [95, 99, 99.9]
}
}
}
}
{
"aggs": {
"load_time_ranks": {
"percentile_ranks": {
"field": "load_time",
"values": [500, 1000]
}
}
}
}
{
"aggs": {
"top_tags": {
"terms": { "field": "tags" },
"aggs": {
"top_tag_hits": {
"top_hits": {
"size": 1,
"sort": [{ "date": { "order": "desc" } }]
}
}
}
}
}
}
基本桶聚合
{
"aggs": {
"genres": {
"terms": {
"field": "genre",
"size": 10,
"order": { "_count": "desc" }
}
}
}
}
{
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"ranges": [
{ "to": 50 },
{ "from": 50, "to": 100 },
{ "from": 100 }
]
}
}
}
}
{
"aggs": {
"date_ranges": {
"date_range": {
"field": "date",
"format": "yyyy-MM-dd",
"ranges": [
{ "to": "now-10d/d" },
{ "from": "now-10d/d", "to": "now" },
{ "from": "now" }
]
}
}
}
}
{
"aggs": {
"prices": {
"histogram": {
"field": "price",
"interval": 50,
"extended_bounds": {
"min": 0,
"max": 500
}
}
}
}
}
{
"aggs": {
"sales_over_time": {
"date_histogram": {
"field": "date",
"calendar_interval": "month",
"format": "yyyy-MM-dd",
"min_doc_count": 0
}
}
}
}
高级桶聚合
{
"aggs": {
"comments": {
"nested": { "path": "comments" },
"aggs": {
"by_user": {
"terms": { "field": "comments.user" }
}
}
}
}
}
{
"aggs": {
"high_value": {
"filter": { "range": { "price": { "gte": 100 } } },
"aggs": {
"avg_price": { "avg": { "field": "price" } }
}
}
}
}
{
"aggs": {
"messages": {
"filters": {
"filters": {
"errors": { "term": { "level": "error" } },
"warnings": { "term": { "level": "warning" } }
}
}
}
}
}
基础管道聚合
{
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"sales": { "sum": { "field": "price" } }
}
},
"avg_monthly_sales": {
"avg_bucket": {
"buckets_path": "sales_per_month>sales"
}
}
}
}
{
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"sales": { "sum": { "field": "price" } },
"sales_deriv": {
"derivative": { "buckets_path": "sales" }
}
}
}
}
}
高级管道聚合
{
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"sales": { "sum": { "field": "price" } },
"cumulative_sales": {
"cumulative_sum": { "buckets_path": "sales" }
}
}
}
}
}
{
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"sales": { "sum": { "field": "price" } },
"moving_avg": {
"moving_avg": { "buckets_path": "sales" }
}
}
}
}
}
排序是 Elasticsearch 搜索中非常重要的功能,它决定了返回结果的顺序。
{
"query": { ... },
"sort": [
{ "field_name": { "order": "desc" } }
]
}
{
"query": { ... },
"sort": [
{ "price": { "order": "asc" } },
{ "date": { "order": "desc" } }
]
}
{
"sort": [
{ "price": { "order": "asc" } }
]
}
{
"query": { "match": { "title": "elasticsearch" } },
"sort": [
"_score",
{ "date": "desc" }
]
}
{
"sort": "_doc"
}
{
"sort": "_shard_doc"
}
{
"sort": [
{
"dates": {
"order": "asc",
"mode": "min", // min/max/avg/sum/median
"nested": {
"path": "dates",
"filter": { "range": { "dates.date": { "gte": "now-1y/y" } } }
}
}
}
]
}
当字段是多值字段时,需要指定使用哪个值进行排序:
模式 | 描述 |
---|---|
min | 使用最小值排序 |
max | 使用最大值排序 |
sum | 使用所有值的和排序 |
avg | 使用平均值排序 |
median | 使用中位数排序 |
示例:
{
"sort": [
{
"prices": {
"order": "asc",
"mode": "avg"
}
}
]
}
{
"sort": [
{
"_geo_distance": {
"field": "location",
"points": [ { "lat": 40.715, "lon": -73.988 } ],
"order": "asc",
"unit": "km",
"distance_type": "arc"
}
}
]
}
{
"sort": [
{
"_geo_distance": {
"location": [ "40.715,-73.988", "41.602,-73.087" ],
"order": "asc",
"unit": "km"
}
}
]
}
使用自定义脚本进行排序:
{
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "doc['price'].value * params.factor",
"params": {
"factor": 1.1
}
},
"order": "desc"
}
}
}
基本嵌套排序
{
"sort": [
{
"comments.date": {
"order": "desc",
"nested": {
"path": "comments"
}
}
}
]
}
带过滤的嵌套排序
{
"sort": [
{
"comments.date": {
"order": "asc",
"nested": {
"path": "comments",
"filter": {
"term": { "comments.verified": true }
}
}
}
}
]
}
_source 参数是 Elasticsearch 查询 DSL 中一个非常重要的功能,它控制着查询结果中原始文档(source document)的返回方式。合理使用 _source 可以显著优化查询性能并减少网络传输量。
_source 是 Elasticsearch 存储的原始 JSON 文档。默认情况下,当你执行搜索时,Elasticsearch 会返回完整的 _source 文档。
禁用 _source 返回
{
"_source": false,
"query": {
"match_all": {}
}
}
返回特定字段
{
"_source": ["field1", "field2"],
"query": {
"match_all": {}
}
}
使用通配符
{
"_source": ["user.*", "*.id"],
"query": {
"match_all": {}
}
}
包含/排除模式
{
"_source": {
"includes": ["*.name", "user.*"],
"excludes": ["user.password", "*.secret"]
},
"query": {
"match_all": {}
}
}
嵌套字段控制
{
"_source": {
"includes": ["user.name", "comments.text"],
"excludes": ["user.email", "comments.ip"]
},
"query": {
"match_all": {}
}
}
script_fields 是 Elasticsearch 查询 DSL 中一个强大的功能,它允许你在查询结果中动态计算并返回新的字段值,而不需要这些字段实际存储在文档中。
基本语法结构
{
"query": { ... },
"script_fields": {
"field_name": {
"script": {
"source": "script_source",
"params": { ... }
}
}
}
}
核心特点
简单计算字段
{
"query": { "match_all": {} },
"script_fields": {
"discounted_price": {
"script": {
"source": "doc['price'].value * 0.9"
}
}
}
}
使用参数
{
"query": { "match_all": {} },
"script_fields": {
"final_price": {
"script": {
"source": "doc['price'].value * params.discount",
"params": {
"discount": 0.85
}
}
}
}
}
多字段计算
{
"query": { "match_all": {} },
"script_fields": {
"total_value": {
"script": {
"source": "doc['price'].value * doc['quantity'].value"
}
}
}
}
条件逻辑
{
"script_fields": {
"price_category": {
"script": {
"source": """
double price = doc['price'].value;
if (price < 50) return 'low';
else if (price < 200) return 'medium';
else return 'high';
"""
}
}
}
}
处理数组字段
{
"script_fields": {
"avg_rating": {
"script": {
"source": """
if (doc['ratings'].size() == 0) return 0;
double sum = 0;
for (rating in doc['ratings']) {
sum += rating;
}
return sum / doc['ratings'].size();
"""
}
}
}
}
日期处理
{
"script_fields": {
"days_since_post": {
"script": {
"source": """
ChronoUnit.DAYS.between(
doc['post_date'].value,
Instant.now()
)
""",
"lang": "painless"
}
}
}
}
高亮(highlight)是 Elasticsearch 中一个非常有用的功能,它能够将查询匹配到的关键词在返回的文本内容中标记出来,便于用户快速定位匹配内容。
基本语法结构
{
"query": { ... },
"highlight": {
"fields": {
"field_name": { ... }
}
}
}
简单示例
{
"query": {
"match": { "content": "Elasticsearch" }
},
"highlight": {
"fields": {
"content": {}
}
}
}
高亮标签设置
{
"highlight": {
"pre_tags": [""],
"post_tags": [""],
"fields": {
"content": {}
}
}
}
高亮片段控制
{
"highlight": {
"fields": {
"content": {
"fragment_size": 150,
"number_of_fragments": 3,
"no_match_size": 150
}
}
}
}
高亮策略
{
"highlight": {
"fields": {
"content": {
"type": "plain", // 或"fvh"(fast vector highlighter),"unified"
"boundary_scanner": "sentence"
}
}
}
}
多字段高亮
{
"highlight": {
"fields": {
"title": {},
"content": {
"number_of_fragments": 5
}
}
}
}
不同字段不同标签
{
"highlight": {
"pre_tags": [""],
"post_tags": [""],
"fields": {
"title": {
"pre_tags": [""],
"post_tags": [""]
},
"content": {}
}
}
}
短语高亮优化
{
"query": {
"match_phrase": { "content": "Elasticsearch tutorial" }
},
"highlight": {
"fields": {
"content": {
"phrase_limit": 10,
"highlight_query": {
"bool": {
"should": [
{ "match": { "content": "Elasticsearch" } },
{ "match": { "content": "tutorial" } }
]
}
}
}
}
}
}