查询 DSL

查询 DSL #

Easysearch 提供了一种名为查询领域特定语言(DSL,query domain-specific language)的搜索语言,您可以使用它来搜索您的数据。查询 DSL 是一种具有 JSON 接口的灵活语言。

使用查询 DSL,您需要在搜索的 query 参数中指定查询。Easysearch 中最简单的搜索之一是使用 match_all 查询,它匹配索引中的所有文档:

GET testindex/_search
{
  "query": {
     "match_all": {
     }
  }
}

一个查询可以由多个查询子句组成。您可以将查询子句组合起来生成复杂的查询。

广义上,你可以将查询分为两类——叶子查询和复合查询:

  • 叶子查询:叶子查询在特定字段或多个字段中搜索指定的值。你可以单独使用叶子查询。它们包括以下查询类型:

    • 精确查询:使用精确查询在文档中搜索确切的词项,例如 ID 或值范围。精确查询不会分析搜索词项或按相关性分数排序结果。
    • 地理和 xy 查询:使用地理查询搜索包含地理数据的文档。使用 xy 查询搜索包含二维坐标系中点和形状的文档。
    • 全文检索:使用全文检索来搜索文本文档。对于分析文本字段的搜索,全文检索使用与字段索引时相同的分词器将查询字符串拆分为词项。对于精确值搜索,全文检索会查找指定的值,而不会应用文本分析。
    • 关联查询:使用关联查询搜索嵌套字段或返回符合特定查询的父文档和子文档。连接查询的类型包括 nestedhas_childhas_parentparent_id 查询。
    • Span 查询:使用 span 查询执行精确的位置搜索。span 查询是低维度的、特定的查询,可控制指定查询词的顺序和邻近度。它们主要用于搜索规则性分词的文档。
    • 特殊查询:特殊查询包括所有其他查询类型( distance_featuremore_like_thispercolaterank_featurescriptscript_scorewrapper )。
  • 复合查询:复合查询作为多个叶子或复合子句的包装器,用于组合其结果或修改其行为。它们包括布尔查询、disjunction max 查询、constant score 查询、function score 查询和 boosting 查询类型。了解更多,请参阅复合查询。

文本字段中 Unicode 特殊字符的说明 #

由于 Unicode 特殊字符与词边界相关联,当文本字段类型值包含这些特殊字符之一时,Unicode 标准分词器不能将其作为整体值进行索引。因此,包含特殊字符的文本字段值会被标准分词器解析为多个由特殊字符分隔的值,实际上将它们两侧的不同元素进行分词。这可能导致文档的意外过滤,并可能损害对其访问的控制。

以下示例说明了包含特殊字符的值,这些值将被标准分词器错误解析。在这个例子中,值中的连字符-的存在阻止了分词器区分 user.id 的两个不同用户,并将它们解释为同一个:

{
  "bool": {
    "must": {
      "match": {
        "user.id": "User-1"
      }
    }
  }
}

{
  "bool": {
    "must": {
      "match": {
        "user.id": "User-2"
      }
    }
  }
}

在使用查询 DSL 或 REST API 时,为了避免这种情况,你可以使用自定义分词器或将字段映射为 keyword ,后者执行精确匹配搜索。有关此选项的更多信息,请参阅 Keyword 字段类型。

昂贵的查询 #

昂贵的查询可能会消耗大量内存,并导致集群性能下降。以下查询可能会消耗资源:

  • fuzzy 查询
  • prefix 查询
  • range 字段上的 textkeyword 查询
  • regexp 查询
  • wildcard 查询
  • query_string 内部转换为前缀查询的查询

要禁止高代价查询,你可以按照以下方式禁用 search.allow_expensive_queries 集群设置:

PUT _cluster/settings
{
  "persistent": {
    "search.allow_expensive_queries": false
  }
}

要跟踪昂贵查询,启用分片慢查询日志。