搜索 API 和模板
Elastic Stack Serverless
您的 搜索应用程序 使用 搜索模板 来执行搜索。模板通过仅公开模板参数来帮助减少复杂性,同时利用 Elasticsearch 查询 DSL 的全部功能来制定查询。可以在创建或更新搜索应用程序时设置模板,并且可以对其进行自定义。此模板可以使用 Put Search Application API API 调用随时进行编辑或更新。
简而言之,您创建带有参数的搜索模板,而不是特定的硬编码搜索值。在搜索时,您传入这些参数的实际值,从而无需重写整个查询结构即可进行自定义搜索。搜索应用程序模板
- 简化查询请求
- 减小请求大小
- 确保安全性和性能,因为查询是预定义的,不能任意更改
本文档提供了信息和示例模板,以帮助您开始使用 搜索应用程序 来处理更多用例。这些模板设计为易于修改以满足您的需求。一旦您创建了带有模板的搜索应用程序,您就可以使用此模板搜索您的搜索应用程序。
如果搜索应用程序未存储任何模板,则在搜索时将应用一个最小的 默认搜索模板。默认模板实现了一个简单的搜索用例。
要创建带有默认模板的搜索应用程序,请在不指定模板的情况下发出 创建或更新搜索应用程序 请求。
PUT _application/search_application/my_search_application {
"indices": ["index1", "index2"]
}
然后,您可以使用 获取搜索应用程序 API 调用来查看新创建的搜索应用程序,其中还将包含为您创建的默认模板。
GET _application/search_application/my_search_application
在这种情况下,响应将是
{
"name": "my_search_application",
"indices": [
"index1",
"index2"
],
"updated_at_millis": 1715802354482,
"template": {
"script": {
"source": """{
"query": {
"query_string": {
"query": "{{query_string}}",
"default_field": "{{default_field}}"
}
}
}
""",
"lang": "mustache",
"params": {
"default_field": "*",
"query_string": "*"
}
}
}
}
默认模板非常基础
{
"template": {
"script": {
"source": {
"query": {
"query_string": {
"query": "{{query_string}}",
"default_field": "{{default_field}}"
}
}
},
"params": {
"query_string": "*",
"default_field": "*"
}
}
}
}
这可能有助于初步探索搜索模板,但您很可能会想要更新它。
此模板不支持其他参数,包括 from、size 或 boost。如果您需要使用这些参数,可以相应地自定义与搜索应用程序关联的模板以将它们包含为参数。
您可以通过查看模板来查看参数及其默认值,但查看如果您使用各种参数 搜索您的搜索应用程序 时将生成的查询也可能很有价值。
您可以使用 渲染搜索应用程序查询 来查看此模板将生成的查询,包括默认参数。例如,在不带参数的情况下搜索搜索应用程序
POST _application/search_application/my_search_application/_render_query
将返回
{
"query": {
"query_string": {
"query": "*",
"default_field": "*",
"fields": []
}
}
}
这使用了模板中定义的默认参数。您还可以向渲染调用指定一个或多个参数,例如
POST _application/search_application/my_search_application/_render_query {
"params": {
"query_string": "rock climbing"
}
}
将返回
{
"query": {
"query_string": {
"query": "rock climbing",
"default_field": "*",
"fields": []
}
}
}
在这种情况下,{{query_string}} 参数已被替换为 rock climbing 的值,而 {{default_field}} 参数未指定,因此使用了默认值 *。
当您实际进行搜索而未提供任何参数时,它将执行渲染调用返回的基础查询。在这种情况下,不带参数的搜索将返回所有结果,类似于对 /_search 的无参数调用。
POST _application/search_application/my_search_application/_search
使用 query_string 和/或 default_field 参数进行搜索将执行 query_string 查询。
默认模板可能会在搜索应用程序功能的未来版本中发生更改。
尝试本文档中的其他示例来尝试特定的用例,或者尝试创建自己的示例!
与搜索应用程序交互的最简单方法是使用与其一起创建和存储的搜索模板。每个搜索应用程序都关联一个模板,该模板定义了搜索条件、参数和默认值。
您使用 搜索应用程序搜索 API 将搜索请求发送到搜索应用程序。
使用默认模板时,搜索如下所示:
POST _application/search_application/my_search_application/_search {
"params": {
"query_string": "kayaking"
}
}
在此示例中,我们覆盖了 query_string 参数的默认值 *。由于我们没有指定 default_field,此参数的值仍将是 *。
如果您不想为搜索应用程序设置搜索模板,将创建一个与搜索应用程序同名的别名。这在尝试特定搜索查询以用于构建搜索应用程序的搜索模板时可能很有用。
如果您的搜索应用程序名称为 my_search_application,则您的别名将是 my_search_application。您可以使用 搜索 API 来搜索它。
搜索应用程序目前不支持跨集群搜索,因为无法将远程集群的索引或索引模式添加到别名中。
您应该使用搜索应用程序管理 API 来更新您的应用程序,*不要* 直接使用 Elasticsearch API,例如别名 API。例如,使用带有 indices 参数的 PUT Search Application。这将自动保持关联的别名最新,并确保正确将索引添加到搜索应用程序。
我们创建了许多示例来探索特定的用例。将这些用作创建您自己的搜索模板的起点。
以下模板支持在指定的字段和权重上进行 multi_match 搜索。
PUT _application/search_application/my_search_application {
"indices": ["index1", "index2"],
"template": {
"script": {
"lang": "mustache",
"source": """
{
"query": {
"multi_match": {
"query": "{{query_string}}",
"fields": [{{#text_fields}}"{{name}}^{{boost}}",{{/text_fields}}]
}
},
"explain": "{{explain}}",
"from": "{{from}}",
"size": "{{size}}"
}
""",
"params": {
"query_string": "*",
"text_fields": [
{"name": "title", "boost": 10},
{"name": "description", "boost": 5}
],
"explain": false,
"from": 0,
"size": 10
}
}
}
}
使用此模板的搜索查询可能如下所示:
POST _application/search_application/my_search_application/_search {
"params": {
"size": 5,
"query_string": "mountain climbing",
"text_fields": [
{"name": "title", "boost": 10},
{"name": "description", "boost": 2},
{"name": "state", "boost": 1}
]
}
}
text_fields 参数可以被新的/不同的字段和权重覆盖,以试验适合您用例的最佳配置。此模板还通过参数支持分页和 explain。
此示例支持 [倒数排名融合 (RRF)]](elasticsearch://reference/elasticsearch/rest-apis/reciprocal-rank-fusion.md) 方法,用于组合 BM25 和 ELSER 搜索。倒数排名融合持续改进不同搜索算法的组合结果。它优于所有其他排名算法,并且通常能超越最佳的单个结果,而无需校准。
PUT _application/search_application/my-search-app {
"indices": [
"index1"
],
"template": {
"script": {
"lang": "mustache",
"source": """
{
"retriever": {
"rrf": {
"retrievers": [
{{#text_fields}}
{
"standard": {
"query": {
"match": {
"{{.}}": "{{query_string}}"
}
}
}
},
{{/text_fields}}
{{#elser_fields}}
{
"standard": {
"query": {
"sparse_vector": {
"field": "ml.inference.{{.}}_expanded.predicted_value",
"inference_id": "<elser_inference_id>",
"query": "{{query_string}}"
}
}
}
},
{{/elser_fields}}
],
"rank_window_size": {{rrf.rank_window_size}},
"rank_constant": {{rrf.rank_constant}}
}
}
}
""",
"params": {
"elser_fields": ["title", "meta_description"],
"text_fields": ["title", "meta_description"],
"query_string": "",
"rrf": {
"rank_window_size": 100,
"rank_constant": 60
}
}
}
}
}
将 <elser_model_id> 替换为您 ELSER 部署的模型 ID。
此模板的示例查询如下所示:
POST _application/search_application/my-search-app/_search {
"params": {
"query_string": "What is the most popular brand of coffee sold in the United States?",
"elser_fields": ["title", "meta_description"],
"text_fields": ["title", "meta_description"],
"rrf": {
"rank_window_size": 50,
"rank_constant": 25
}
}
}
Elastic Learned Sparse EncodeR (ELSER) 通过文本扩展提高搜索相关性,从而实现语义搜索。此实验性模板要求在的一个或多个字段上启用 ELSER。有关如何使用 ELSER 的更多信息,请参阅 使用 ELSER 进行语义搜索。在此情况下,ELSER 在 title 和 description 字段上启用。
此示例提供了一个模板,可用于各种搜索应用程序场景:文本搜索、ELSER 或两者兼有。如果未指定参数,它还提供了一个简单的默认 query_string 查询。
PUT _application/search_application/my_search_application {
"indices": [
"index1",
"index2"
],
"template": {
"script": {
"lang": "mustache",
"source": """
{
"query": {
"bool": {
"should": [
{{#text}}
{
"multi_match": {
"query": "{{query_string}}",
"fields": [{{#text_fields}}"{{name}}^{{boost}}",{{/text_fields}}],
"boost": "{{text_query_boost}}"
}
},
{{/text}}
{{#elser}}
{{#elser_fields}}
{
"sparse_vector": {
"field": "ml.inference.{{.}}_expanded.predicted_value",
"inference_id": "<elser_inference_id>",
"query": "{{query_string}}"
}
},
{{/elser_fields}}
{ "bool": { "must": [] } },
{{/elser}}
{{^text}}
{{^elser}}
{
"query_string": {
"query": "{{query_string}}",
"default_field": "{{default_field}}",
"default_operator": "{{default_operator}}",
"boost": "{{text_query_boost}}"
}
},
{{/elser}}
{{/text}}
{ "bool": { "must": [] } }
],
"minimum_should_match": 1
}
},
"min_score": "{{min_score}}",
"explain": "{{explain}}",
"from": "{{from}}",
"size": "{{size}}"
}
""",
"params": {
"text": false,
"elser": false,
"elser_fields": [
{"name": "title", "boost": 1},
{"name": "description", "boost": 1}
],
"text_fields": [
{"name": "title", "boost": 10},
{"name": "description", "boost": 5},
{"name": "state", "boost": 1}
],
"query_string": "*",
"text_query_boost": 4,
"default_field": "*",
"default_operator": "OR",
"explain": false,
"from": 0,
"size": 10,
"min_score": 0
}
}
}
}
使用此模板的文本搜索查询可能如下所示:
POST _application/search_application/my_search_application/_search {
"params": {
"text": true,
"size": 5,
"query_string": "mountain climbing",
"text_fields": [
{"name": "title", "boost": 10},
{"name": "description", "boost": 5},
{"name": "state", "boost": 1}
]
}
}
使用此模板的 ELSER 搜索查询将如下所示:
POST _application/search_application/my_search_application/_search {
"params": {
"elser": true,
"query_string": "where is the best mountain climbing?",
"elser_fields": [
{"name": "title", "boost": 1},
{"name": "description", "boost": 1}
]
}
}
使用此模板的组合文本搜索和 ELSER 搜索查询将如下所示:
POST _application/search_application/my_search_application/_search {
"params": {
"elser": true,
"text": true,
"query_string": "where is the best mountain climbing?",
"elser_fields": [
{"name": "title", "boost": 1},
{"name": "description", "boost": 1}
],
"text_query_boost": 4,
"min_score": 10
}
}
文本搜索结果和 ELSER 搜索结果在某些情况下得分会显著不同,这使得排名变得困难。为了找到数据集的最佳搜索结果组合,我们建议尝试示例模板中提供的权重值
上述权重对于许多用例来说应该足够了,但在某些情况下,添加 rescore 查询或 index boost 到模板可能会有益。请记住使用 put search application 命令 更新您的搜索应用程序以使用新模板。
最后,使用此模板进行无参数搜索将回退到返回所有文档的默认搜索。
POST _application/search_application/my_search_application/_search
此示例支持 ELSER 搜索的精简版本。
PUT _application/search_application/my_search_application {
"indices": [
"index1",
"index2"
],
"template": {
"script": {
"lang": "mustache",
"source": """
{
"query": {
"bool": {
"should": [
{{#elser_fields}}
{
"sparse_vector": {
"field": "ml.inference.{{.}}_expanded.predicted_value",
"inference_id": "<elser_inference_id>",
"query": "{{query_string}}"
}
},
{{/elser_fields}}
]
}
},
"min_score": "{{min_score}}"
}
""",
"params": {
"query_string": "*",
"min_score": "10",
"elser_fields": [
{
"name": "title"
},
{
"name": "description"
}
]
}
}
}
}
将 <elser_model_id> 替换为您 ELSER 部署的模型 ID。
此模板的示例查询如下所示:
POST _application/search_application/my_search_application/_search {
"params": {
"query_string": "Where is the best place for mountain climbing?"
}
}
此示例支持 k-近邻 (kNN) 搜索。
支持精确 kNN 搜索的模板将如下所示:
PUT _application/search_application/my_search_application {
"indices": [
"index1"
],
"template": {
"script": {
"lang": "mustache",
"source": """
{
"query": {
"script_score": {
"query": {
"bool": {
"filter": {
"range": {
"{{field}}": {
"{{operator}}": {{value}}
}
}
}
}
},
"script": {
"source": "cosineSimilarity({{#toJson}}query_vector{{/toJson}}, '{{dense_vector_field}}') + 1.0"
}
}
}
}
""",
"params": {
"field": "price",
"operator": "gte",
"value": 1000,
"dense_vector_field": "product-vector",
"query_vector": []
}
}
}
}
使用此模板的搜索查询将如下所示:
POST _application/search_application/my_search_application/_search {
"params": {
"field": "price",
"operator": "gte",
"value": 500
}
}
支持近似 kNN 搜索的模板将如下所示:
PUT _application/search_application/my_search_application {
"indices": [
"index1"
],
"template": {
"script": {
"lang": "mustache",
"source": """
{
"knn": {
"field": "{{knn_field}}",
"query_vector": {{#toJson}}query_vector{{/toJson}},
"k": "{{k}}",
"num_candidates": {{num_candidates}}
},
"fields": {{#toJson}}fields{{/toJson}}
}
""",
"params": {
"knn_field": "image-vector",
"query_vector": [],
"k": 10,
"num_candidates": 100,
"fields": ["title", "file-type"]
}
}
}
}
使用此模板的搜索查询将如下所示:
POST _application/search_application/my_search_application/_search {
"params": {
"knn_field": "image-vector",
"query_vector": [-5, 9, -12],
"k": 10,
"num_candidates": 100,
"fields": ["title", "file-type"]
}
}