
# 使用DSL语言搜索数据
当用户需要与OpenSearch集群进行交互以执行复杂的全文检索或数据分析时，DSL (Domain Specific Language) 作为OpenSearch的原生查询语言，基于JSON格式构建，能够精确表达查询意图，是客户端与OpenSearch集群交互的最佳语言。
#### 什么是DSL？
DSL是OpenSearch定义的一套基于JSON的请求体格式。它主要包含两个上下文：
- Query Context（查询上下文）：回答"这个文档与查询子句匹配程度如何？"的问题。会计算"_score"（相关性评分），用于结果排序。例如：match。
- Filter Context（过滤上下文）：回答"这个文档是否匹配？"的问题（Yes/No）。不计算评分，且结果会被OpenSearch自动缓存，性能更高。例如：term、range。
DSL查询在OpenSearch Dashboards的Dev Tools中执行，请求体和返回信息都是JSON格式。
本文列举了常用DSL查询语句，全量的DSL查询语句请参见[Query DSL](https://opensearch.org/docs/latest/query-dsl/)。
#### 基础查询：匹配所有
使用"match_all"查询以获取索引中的所有文档，相当于SQL语言中的"SELECT \* FROM table"。适用于需要检索所有记录的场景。
例如，执行如下命令，在"test"索引中匹配所有文档。
```
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"用于聚合。
