搜索数据
在 OpenSearch 中,有几种搜索数据的方法
- 查询领域特定语言 (DSL):主要的 OpenSearch 查询语言,您可以使用它来创建复杂的、完全可定制的查询。
- 查询字符串查询语言:一种简化的查询语言,您可以在搜索请求的查询参数或 OpenSearch Dashboards 中使用。
- SQL:一种传统的查询语言,它弥合了传统关系数据库概念与 OpenSearch 面向文档的数据存储的灵活性之间的差距。
- 管道处理语言 (PPL):用于 OpenSearch 可观测性的主要语言。PPL 使用管道语法将命令链接到查询中。
- Dashboards 查询语言 (DQL):一种简单的基于文本的查询语言,用于在 OpenSearch Dashboards 中过滤数据。
本教程简要介绍了如何使用 查询字符串查询和 查询 DSL 进行搜索。
准备数据
对于本教程,如果您尚未这样做,则需要为学生数据建立索引。您可以先删除 students
索引 (DELETE /students
),然后发送以下批量请求
POST _bulk
{ "create": { "_index": "students", "_id": "1" } }
{ "name": "John Doe", "gpa": 3.89, "grad_year": 2022}
{ "create": { "_index": "students", "_id": "2" } }
{ "name": "Jonathan Powers", "gpa": 3.85, "grad_year": 2025 }
{ "create": { "_index": "students", "_id": "3" } }
{ "name": "Jane Doe", "gpa": 3.52, "grad_year": 2024 }
检索索引中的所有文档
要检索索引中的所有文档,请发送以下请求
GET /students/_search
前面的请求等效于 match_all
查询,该查询匹配索引中的所有文档
GET /students/_search
{
"query": {
"match_all": {}
}
}
OpenSearch 返回匹配的文档
{
"took": 12,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "students",
"_id": "1",
"_score": 1,
"_source": {
"name": "John Doe",
"gpa": 3.89,
"grad_year": 2022
}
},
{
"_index": "students",
"_id": "2",
"_score": 1,
"_source": {
"name": "Jonathan Powers",
"gpa": 3.85,
"grad_year": 2025
}
},
{
"_index": "students",
"_id": "3",
"_score": 1,
"_source": {
"name": "Jane Doe",
"gpa": 3.52,
"grad_year": 2024
}
}
]
}
}
响应正文字段
前面的响应包含以下字段。
took
took
字段包含查询运行所花费的时间,以毫秒为单位。
timed_out
此字段指示请求是否超时。如果请求超时,则 OpenSearch 返回在超时之前收集的结果。您可以通过提供 timeout
查询参数来设置所需的超时值
GET /students/_search?timeout=20ms
_shards
_shards
对象指定查询运行的总分片数以及成功或失败的分片数。如果分片本身及其所有副本都不可用,则分片可能会失败。如果任何涉及的分片失败,OpenSearch 将继续在剩余的分片上运行查询。
hits
hits
对象包含匹配文档的总数和文档本身(在 hits
数组中列出)。每个匹配的文档都包含 _index
和 _id
字段以及 _source
字段,其中包含完整的原始索引文档。
每个文档在 _score
字段中都有一个相关性分数。因为您运行了 match_all
搜索,所以所有文档的分数都设置为 1
(它们的相关性没有差异)。max_score
字段包含任何匹配文档的最高分数。
查询字符串查询
查询字符串查询是轻量级的但功能强大。您可以将查询字符串查询作为 q
查询参数发送。例如,以下查询搜索名称为 john
的学生
GET /students/_search?q=name:john
OpenSearch 返回匹配的文档
{
"took": 18,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.9808291,
"hits": [
{
"_index": "students",
"_id": "1",
"_score": 0.9808291,
"_source": {
"name": "John Doe",
"grade": 12,
"gpa": 3.89,
"grad_year": 2022,
"future_plans": "John plans to be a computer science major"
}
}
]
}
}
有关查询字符串语法的更多信息,请参阅 查询字符串查询语言。
查询 DSL
使用查询 DSL,您可以创建更复杂和自定义的查询。
全文搜索
您可以对映射为 text
的字段运行全文搜索。默认情况下,文本字段由 default
分析器分析。分析器将文本拆分为术语并将其更改为小写。有关 OpenSearch 分析器的更多信息,请参阅 分析器。
例如,以下查询搜索名称为 john
的学生
GET /students/_search
{
"query": {
"match": {
"name": "john"
}
}
}
响应包含匹配的文档
{
"took": 13,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.9808291,
"hits": [
{
"_index": "students",
"_id": "1",
"_score": 0.9808291,
"_source": {
"name": "John Doe",
"gpa": 3.89,
"grad_year": 2022
}
}
]
}
}
请注意,查询文本是小写的,而字段中的文本不是,但查询仍然返回匹配的文档。
您可以重新排序搜索字符串中的术语。例如,以下查询搜索 doe john
GET /students/_search
{
"query": {
"match": {
"name": "doe john"
}
}
}
响应包含两个匹配的文档
{
"took": 14,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1.4508327,
"hits": [
{
"_index": "students",
"_id": "1",
"_score": 1.4508327,
"_source": {
"name": "John Doe",
"gpa": 3.89,
"grad_year": 2022
}
},
{
"_index": "students",
"_id": "3",
"_score": 0.4700036,
"_source": {
"name": "Jane Doe",
"gpa": 3.52,
"grad_year": 2024
}
}
]
}
}
match 查询类型默认使用 OR
作为运算符,因此查询在功能上是 doe OR john
。John Doe
和 Jane Doe
都匹配了单词 doe
,但 John Doe
的得分更高,因为它也匹配了 john
。
关键字搜索
name
字段包含 name.keyword
子字段,该字段由 OpenSearch 自动添加。如果您以类似于先前请求的方式搜索 name.keyword
字段
GET /students/_search
{
"query": {
"match": {
"name.keyword": "john"
}
}
}
然后,请求将不返回任何点击,因为 keyword
字段必须完全匹配。
但是,如果您搜索确切的文本 John Doe
GET /students/_search
{
"query": {
"match": {
"name.keyword": "John Doe"
}
}
}
OpenSearch 返回匹配的文档
{
"took": 19,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.9808291,
"hits": [
{
"_index": "students",
"_id": "1",
"_score": 0.9808291,
"_source": {
"name": "John Doe",
"gpa": 3.89,
"grad_year": 2022
}
}
]
}
}
过滤器
使用布尔查询,您可以向查询中添加过滤器子句,以用于具有确切值的字段
术语过滤器匹配特定术语。例如,以下布尔查询搜索毕业年份为 2022 年的学生
GET students/_search
{
"query": {
"bool": {
"filter": [
{ "term": { "grad_year": 2022 }}
]
}
}
}
使用范围过滤器,您可以指定值的范围。例如,以下布尔查询搜索 GPA 大于 3.6 的学生
GET students/_search
{
"query": {
"bool": {
"filter": [
{ "range": { "gpa": { "gt": 3.6 }}}
]
}
}
}
有关过滤器的更多信息,请参阅 查询和过滤器上下文。
复合查询
复合查询允许您组合多个查询或过滤器子句。布尔查询是复合查询的一个示例。
例如,要搜索名称与 doe
匹配的学生,并按毕业年份和 GPA 过滤,请使用以下请求
GET students/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "doe"
}
},
{ "range": { "gpa": { "gte": 3.6, "lte": 3.9 } } },
{ "term": { "grad_year": 2022 }}
]
}
}
}
有关布尔和其他复合查询的更多信息,请参阅 复合查询。
搜索方法
除了本教程中描述的传统全文搜索之外,OpenSearch 还支持一系列机器学习 (ML) 驱动的搜索方法,包括 k-NN、语义、多模态、稀疏、混合和会话搜索。有关所有 OpenSearch 支持的搜索方法的信息,请参阅 搜索。