查询 DSL
OpenSearch 提供了一种名为查询领域特定语言 (DSL) 的搜索语言,可用于搜索数据。查询 DSL 是一种灵活的语言,具有 JSON 接口。
使用查询 DSL,您需要在搜索的 query
参数中指定一个查询。OpenSearch 中最简单的搜索之一是使用 match_all
查询,它匹配索引中的所有文档
GET testindex/_search
{
"query": {
"match_all": {
}
}
}
一个查询可以由许多查询子句组成。您可以组合查询子句来生成复杂查询。
大体上,查询可以分为两类——叶查询和复合查询
-
叶查询:叶查询在特定字段或多个字段中搜索指定值。您可以单独使用叶查询。它们包括以下查询类型
-
全文查询:使用全文查询来搜索文本文档。对于分析过的文本字段搜索,全文查询使用与索引字段时相同的分析器将查询字符串拆分为词元。对于精确值搜索,全文查询查找指定值而不应用文本分析。
-
词元级别查询:使用词元级别查询来搜索文档中的精确词元,例如 ID 或值范围。词元级别查询不分析搜索词元或根据相关性分数排序结果。
-
地理和 xy 查询:使用地理查询来搜索包含地理数据的文档。使用 xy 查询来搜索包含二维坐标系中的点和形状的文档。
-
连接查询:使用连接查询来搜索嵌套字段,或返回与特定查询匹配的父文档和子文档。连接查询的类型包括
nested
、has_child
、has_parent
和parent_id
查询。 -
跨度查询:使用跨度查询执行精确的位置搜索。跨度查询是低级别、特定查询,可控制指定查询词元的顺序和邻近性。它们主要用于搜索法律文档。
-
专门查询:专门查询包括所有其他查询类型(
distance_feature
、more_like_this
、percolate
、rank_feature
、script
、script_score
和wrapper
)。
-
-
复合查询:复合查询作为多个叶查询或复合子句的包装器,用于组合它们的结果或修改它们的行为。它们包括布尔、析取最大值、常量分数、函数分数和增强查询类型。要了解更多信息,请参阅复合查询。
关于文本字段中的 Unicode 特殊字符的注意事项
由于与 Unicode 特殊字符相关的单词边界,当 Unicode 标准分析器索引包含这些特殊字符的文本字段类型值时,无法将其作为整体值进行索引。结果,包含特殊字符的文本字段值会被标准分析器解析为由特殊字符分隔的多个值,从而有效地对两侧的不同元素进行分词。这可能导致无意中过滤文档,并可能损害对其访问的控制。
以下示例说明了包含特殊字符的值将如何被标准分析器不正确地解析。在此示例中,值中存在的连字符/减号会阻止分析器区分 user.id
的两个不同用户,并将其解释为同一个用户
{
"bool": {
"must": {
"match": {
"user.id": "User-1"
}
}
}
}
{
"bool": {
"must": {
"match": {
"user.id": "User-2"
}
}
}
}
为避免在使用查询 DSL 或 REST API 时出现这种情况,您可以使用自定义分析器或将字段映射为 keyword
类型,后者执行精确匹配搜索。有关后一个选项,请参阅关键字字段类型。
有关在使用 text
字段类型时应避免的字符列表,请参阅单词边界。
高开销查询
高开销查询会消耗大量内存,并导致集群性能下降。以下查询可能资源消耗较高
- `fuzzy` 查询
- `prefix` 查询
- 对 `range` 查询在 `text` 和 `keyword` 字段上的应用
- `regexp` 查询
- `wildcard` 查询
- 内部转换为前缀查询的 `query_string` 查询
要禁止高开销查询,您可以按如下方式禁用 search.allow_expensive_queries
集群设置:
PUT _cluster/settings
{
"persistent": {
"search.allow_expensive_queries": false
}
}
要跟踪高开销查询,请启用分片慢日志。