更新时间:2026-04-24 GMT+08:00
分享

使用DSL语言搜索数据

当用户需要与Elasticsearch集群进行交互以执行复杂的全文检索或数据分析时,DSL (Domain Specific Language) 作为Elasticsearch的原生查询语言,基于JSON格式构建,能够精确表达查询意图,是客户端与Elasticsearch集群交互的最佳语言。

什么是DSL?

DSL是Elasticsearch定义的一套基于JSON的请求体格式。它主要包含两个上下文:

  • Query Context(查询上下文):回答“这个文档与查询子句匹配程度如何?”的问题。会计算“_score”(相关性评分),用于结果排序。例如:match。
  • Filter Context(过滤上下文):回答“这个文档是否匹配?”的问题(Yes/No)。不计算评分,且结果会被Elasticsearch自动缓存,性能更高。例如:term、range。

DSL查询通常在Kibana的Dev Tools中执行,请求体和返回信息都是JSON格式。

本文列举了常用DSL查询语句,全量的DSL查询语句请参见Query DSL

基础查询:匹配所有

使用“match_all”查询以获取索引中的所有文档,相当于SQL语言中的“SELECT * FROM table”。适用于需要检索所有记录的场景。

例如,执行如下命令,在“test”索引中匹配所有文档。

1
2
3
4
5
6
GET /test/_search
{
  "query": {
    "match_all": {}
  }
}

复合查询:多条件组合

使用“bool (must, filter)”查询结构以实现多条件组合查询,相当于SQL语言中的“where”。适用于需要根据多个条件筛选文档的场景。

例如,执行如下命令,查询所有状态为“published”且发布日期在“2015-01-01”之后(过滤条件),同时标题或内容中包含“Search”(搜索条件)的文档。

GET /_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "Search"
          }
        },
        {
          "match": {
            "content": "search"
          }
        }
      ],
      "filter": [
        {
          "term": {
            "status": "published"
          }
        },
        {
          "range": {
            "publish_date": {
              "gte": "2015-01-01"
            }
          }
        }
      ]
    }
  }
}

其中,“must”“filter”字段的区别:

  • must:用于指定必须匹配的条件,且这些条件会影响文档的相关度评分。文档越匹配,分越高,排越前。
  • filter:用于指定必须匹配的条件,但这些条件不会影响文档的相关度评分。性能优于must,适合用于过滤结构化数据。

对于不需要计算相关度分数的条件(如状态、时间范围、类别),建议放入“filter”中以提升性能。

聚合分析

使用“aggs (terms)”查询结构以实现分组聚合查询,相当于SQL语言中的“Group by”。适用于需要对文档进行分组统计的场景。

例如,执行如下命令,统计“test”索引中,不同标题(title)出现的次数。

GET /test/_search
{
  "aggs": {
    "titles": {
      "terms": {
        "field": "title.keyword"
      }
    }
  }
}

使用title.keyword的原因:

  • text类型用于全文检索(分词)。例如Hello World会被拆解为hello和world。直接对“text”字段聚合会报错(Fielddata is disabled),因为它极其消耗内存。
  • keyword类型用于精确匹配和聚合。它保存的是Hello World这个完整字符串。

集群默认会为字符串创建多字段(Multi-field),即“title”用于搜索,“title.keyword”用于聚合。

相关文档