Elasticsearch 8.x DSL 语法速览
185
类别: 
开发交流

Elasticsearch 8.x DSL 语法速览

Elasticsearch 8.x 的查询 DSL(Domain Specific Language)以 JSON 结构描述检索、聚合、排序、分页等需求。掌握 DSL 能精确控制查询行为,并充分发挥倒排索引与分布式搜索的优势。下文按照常用场景,给出核心语法要点与示例。

基本查询

  • match:按分词结果匹配,适合全文检索。
  • match_phrase:强调短语顺序,可通过 slop 设置容错距离。
  • multi_match:一次匹配多个字段,可用 fields 指定权重,如 title^2.
  • term / terms:精确匹配,不分词;常用于 keyword、数字、布尔字段。
GET /products/_search
{
  "query": {
    "multi_match": {
      "query": "无线 蓝牙 耳机",
      "fields": ["title^2", "description"]
    }
  }
}

组合查询

bool 查询通过以下子句组合复杂条件:

  • must: 条件必须满足(逻辑 AND)
  • should: 条件满足越多越好(逻辑 OR),可配合 minimum_should_match
  • must_not: 排除条件
  • filter: 不参与评分,适合范围、精确匹配等
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "耳机" } }
      ],
      "filter": [
        { "term": { "brand": "sony" } },
        { "range": { "price": { "gte": 300, "lte": 800 } } }
      ],
      "must_not": [
        { "term": { "is_discontinued": true } }
      ]
    }
  }
}

范围与日期

range 可用于数字、日期或关键字的字典序比较:

{ "range": { "sale_date": { "gte": "now-30d", "lt": "now" } } }

常见参数:gte, gt, lte, lt, time_zone

聚合分析

Elasticsearch 8.x 聚合 DSL 依然以桶(bucket)与度量(metric)为核心概念:

  • terms: 统计分布
  • date_histogram: 时间序列
  • range / histogram: 自定义区间
  • 度量:avg, sum, max, min, cardinality, top_hits
GET /orders/_search
{
  "size": 0,
  "query": {
    "term": { "status": "paid" }
  },
  "aggs": {
    "sales_by_day": {
      "date_histogram": {
        "field": "paid_at",
        "calendar_interval": "day"
      },
      "aggs": {
        "revenue": { "sum": { "field": "amount" } }
      }
    }
  }
}

排序与评分

  • sort 数组支持多字段排序,可指定 order, mode, missing, unmapped_type
  • track_scores 结合 sort 在需要评分时开启。
  • function_score 可叠加衰减函数(gaussexplinear)、脚本或字段值,调整相关度。

分页与游标

  • from + size:简单分页,适合小页码。
  • search_after:基于排序值的深分页;必须与 sort 搭配,并使用上一页最后一条记录的 sort 值。
  • scroll:长时间、顺序读取大量结果;8.x 推荐以 _pit(Point in Time)+ search_after 组合替代。

高亮与返回字段

  • highlight 支持字段级配置,可设置 pre_tags, post_tags, fragment_size, number_of_fragments
  • _source 可以布尔值、数组或 includes/excludes 形式,控制返回字段。

脚本与运行时字段

  • script(Painless)可用于 script_score, script_fields, update_by_query 等。
  • runtime_mappings 允许在查询时临时计算字段,避免修改映射。
{
  "runtime_mappings": {
    "price_with_tax": {
      "type": "double",
      "script": {
        "source": "emit(doc['price'].value * 1.13)"
      }
    }
  },
  "query": { "match_all": {} },
  "fields": ["price_with_tax"]
}

安全与最佳实践

  • 8.x 默认启用安全特性,使用 API 调用时需携带 API Key 或 Basic Auth。
  • 请求应尽量使用 POST /_search,并在 JSON 中传参,避免 URL 过长。
  • 对频繁执行的复杂查询,可创建索引模板、使用 _search/templatestored script
  • 合理规划映射类型,避免 keyword/全文字段混淆;关注字段数据类型对 DSL 的影响。

通过掌握上述 DSL 结构与模式,可以快速构建 Elasticsearch 8.x 的检索与分析能力。建议在 Kibana Dev Tools 中边写边调试,并结合具体业务索引结构进行迭代优化。

评论 0
/ 1000
0
0
收藏