更新时间:2024-09-14 GMT+08:00

使用DSL语言在Elasticsearch中搜索数据

DSL语言是Elasticsearch和OpenSearch查询域的特定语言,是客户端与Elasticsearch和OpenSearch集群交互的最佳语言。Elasticsearch DSL是基于JSON格式的语言,其他语言如SQL本质上也是先转译为Elasticsearch DSL再与Elasticsearch和OpenSearch集群交互。

DSL使用示例

在Kibana的DevTools中编写请求内容的JSON并执行搜索请求。

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

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

查询结果返回的也是JSON格式的数据。

常用的DSL查询语句

下面列举了常用的DSL查询语句,全量的DSL查询语句请参见《Elasticsearch指南》

  • 设置查询条件过滤,等同于SQL语言中的where。

    如下命令中,查询未在“_search”前面过滤索引,所以是查询所有索引。bool为条件句,filter强制过滤“status”字段为“published”并且“publish_date”字段为“2015-01-01”以后的文档,must规定“title”字段含有“Search”并且“content”字段含有“Search”

    must和filter字段的区别在于filter等同于SQL的where会过滤字段但不参与ES搜索的打分机制,must也属于过滤必须满足的条件,但是会根据查询的匹配程度对搜索到的文档进行打分,在返回的结果中越匹配的文档会越靠前显示。

    GET /_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "title": "Search"
              }
            },
            {
              "match": {
                "content": "search"
              }
            }
          ],
          "filter": [
            {
              "term": {
                "status": "published"
              }
            },
            {
              "range": {
                "publish_date": {
                  "gte": "2015-01-01"
                }
              }
            }
          ]
        }
      }
    }
  • 聚合查询,近似于SQL语言中的Group by。

    该查询是根据genre这个字段进行聚合,会根据test索引里的title字段进行分类统计。如果title为text(含keyword)类型,需要使用“title.keyword”进行聚合,默认情况下Elasticsearch和OpenSearch无法直接对text类型的字段进行聚合。其中titles仅为聚合的命名,可以根据需要命名为titles或者titleaggs等。

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

    以上聚合查询的例子包含了test索引的所有文档,即match_all查询条件为隐式条件。可以配合设置查询条件过滤中的查询条件过滤特定的文档进行聚合。