检索器
编辑检索器
编辑检索器是一种规范,用于描述从搜索返回的顶部文档。检索器取代了搜索 API中其他也返回顶部文档的元素,例如query
和knn
。一个检索器可以有子检索器,其中具有两个或多个子检索器的检索器被认为是复合检索器。这允许在称为检索器树的树状结构中描绘复杂的行为,该树状结构阐明了搜索期间发生的操作顺序。
以下检索器可用
-
标准
- 一个检索器,它取代了传统查询的功能。
-
knn
- 一个检索器,它取代了knn 搜索的功能。
-
rrf
- 一个检索器,它从倒数排名融合 (RRF)产生顶部文档。
-
text_similarity_reranker
- 一个检索器,它通过使用机器学习模型,基于与指定推理文本的语义相似性对文档进行重新排序来增强搜索结果。
-
规则
- 一个检索器,它将上下文使用查询规则进行搜索应用于为特定查询固定或排除文档。
标准检索器
编辑标准检索器从传统查询返回顶部文档。
参数
编辑-
query
-
(可选,查询对象)
定义用于检索一组顶部文档的查询。
-
filter
-
(可选,查询对象或查询对象列表)
对此检索器应用布尔查询过滤器,其中所有文档必须匹配此查询,但不计入分数。
-
search_after
-
(可选,search after 对象)
定义用于分页的 search after 对象参数。
-
terminate_after
-
(可选,整数)为每个分片收集的最大文档数。如果查询达到此限制,Elasticsearch 将提前终止查询。Elasticsearch 在排序之前收集文档。
谨慎使用。Elasticsearch 将此参数应用于处理请求的每个分片。如果可能,请让 Elasticsearch 自动执行提前终止。避免为跨多个数据层针对具有后备索引的数据流的请求指定此参数。
-
sort
-
(可选,排序对象)一个排序对象,用于指定匹配文档的顺序。
-
min_score
-
(可选,
float
)匹配文档的最小
_score
。顶部文档中不包括_score
较低的文档。 -
collapse
-
(可选,折叠对象)
根据指定的键将顶部文档折叠成每个键的单个顶部文档。
限制
编辑当检索器树包含复合检索器(具有两个或多个子检索器的检索器)时,不支持search after参数。
示例
编辑resp = client.search( index="restaurants", retriever={ "standard": { "query": { "bool": { "should": [ { "match": { "region": "Austria" } } ], "filter": [ { "term": { "year": "2019" } } ] } } } }, ) print(resp)
const response = await client.search({ index: "restaurants", retriever: { standard: { query: { bool: { should: [ { match: { region: "Austria", }, }, ], filter: [ { term: { year: "2019", }, }, ], }, }, }, }, }); console.log(response);
kNN 检索器
编辑kNN 检索器从k 近邻搜索 (kNN)返回顶部文档。
参数
编辑-
field
-
(必需,字符串)
要搜索的向量字段的名称。必须是启用了索引的
dense_vector
字段。 -
query_vector
-
(如果未定义
query_vector_builder
,则为必需,float
数组)查询向量。必须与您要搜索的向量字段具有相同的维度数。必须是浮点数数组或十六进制编码的字节向量。
-
query_vector_builder
-
(如果未定义
query_vector
,则为必需,查询向量生成器对象)定义一个模型以构建查询向量。
-
k
-
(必需,整数)
要作为顶部命中返回的最近邻的数量。此值必须小于或等于
num_candidates
。 -
num_candidates
-
(必需,整数)
每个分片要考虑的最近邻候选的数量。需要大于
k
,或者如果省略k
,则大于size
,并且不能超过 10,000。Elasticsearch 从每个分片收集num_candidates
结果,然后合并它们以找到顶部k
个结果。增加num_candidates
往往会提高最终k
个结果的准确性。默认为Math.min(1.5 * k, 10_000)
。 -
filter
-
(可选,查询对象或查询对象列表)
用于过滤可以匹配的文档的查询。kNN 搜索将返回也匹配此过滤器的顶部
k
个文档。该值可以是单个查询或查询列表。如果未提供filter
,则允许所有文档匹配。 -
similarity
-
(可选,浮点数)
文档被视为匹配所需的最小相似度。计算的相似度值与所使用的原始
similarity
相关。不是文档分数。然后,根据similarity
对匹配的文档进行评分,并应用提供的boost
。similarity
参数是直接向量相似度计算。-
l2_norm
:也称为欧几里得,将包括向量位于以query_vector
为原点,半径为similarity
的dims
维超球面内的文档。 -
cosine
、dot_product
和max_inner_product
:仅返回余弦相似度或点积至少为提供的similarity
的向量。
在此处阅读更多内容:kNN 相似度搜索
-
限制
编辑参数 query_vector
和 query_vector_builder
不能一起使用。
示例
编辑resp = client.search( index="restaurants", retriever={ "knn": { "field": "vector", "query_vector": [ 10, 22, 77 ], "k": 10, "num_candidates": 10 } }, ) print(resp)
const response = await client.search({ index: "restaurants", retriever: { knn: { field: "vector", query_vector: [10, 22, 77], k: 10, num_candidates: 10, }, }, }); console.log(response);
RRF 检索器
编辑RRF 检索器根据 RRF 公式返回顶部文档,该公式对两个或多个子检索器进行同等加权。倒数排名融合 (RRF) 是一种将具有不同相关性指标的多个结果集组合为单个结果集的方法。
参数
编辑-
retrievers
-
(必需,检索器对象数组)
一个子检索器列表,用于指定将对其应用 RRF 公式的一组返回的顶部文档。每个子检索器作为 RRF 公式的一部分具有相等的权重。需要两个或多个子检索器。
-
rank_constant
-
(可选,整数)
此值确定每个查询的单个结果集中的文档对最终排名结果集的影响程度。值越高表示排名较低的文档的影响越大。此值必须大于或等于
1
。默认为60
。 -
rank_window_size
-
(可选,整数)
此值决定了每个查询的单个结果集的大小。较高的值会提高结果的相关性,但会牺牲性能。最终的排名结果集会被修剪到搜索请求的 size 大小。
rank_window_size
必须大于或等于size
,且大于或等于1
。默认为size
参数的值。 -
filter
-
(可选,查询对象或查询对象列表)
根据每个检索器的规范,将指定的布尔查询过滤器应用于所有指定的子检索器。
示例:混合搜索
编辑一个简单的混合搜索示例(词法搜索 + 密集向量搜索),使用 RRF 结合 standard
检索器和 knn
检索器
resp = client.search( index="restaurants", retriever={ "rrf": { "retrievers": [ { "standard": { "query": { "multi_match": { "query": "Austria", "fields": [ "city", "region" ] } } } }, { "knn": { "field": "vector", "query_vector": [ 10, 22, 77 ], "k": 10, "num_candidates": 10 } } ], "rank_constant": 1, "rank_window_size": 50 } }, ) print(resp)
const response = await client.search({ index: "restaurants", retriever: { rrf: { retrievers: [ { standard: { query: { multi_match: { query: "Austria", fields: ["city", "region"], }, }, }, }, { knn: { field: "vector", query_vector: [10, 22, 77], k: 10, num_candidates: 10, }, }, ], rank_constant: 1, rank_window_size: 50, }, }, }); console.log(response);
GET /restaurants/_search { "retriever": { "rrf": { "retrievers": [ { "standard": { "query": { "multi_match": { "query": "Austria", "fields": [ "city", "region" ] } } } }, { "knn": { "field": "vector", "query_vector": [10, 22, 77], "k": 10, "num_candidates": 10 } } ], "rank_constant": 1, "rank_window_size": 50 } } }
定义一个带有 RRF 检索器的检索器树。 |
|
子检索器数组。 |
|
第一个子检索器是一个 |
|
第二个子检索器是一个 |
|
RRF 检索器的排名常数。 |
|
RRF 检索器的排名窗口大小。 |
示例:使用稀疏向量的混合搜索
编辑一个更复杂的混合搜索示例(词法搜索 + ELSER 稀疏向量搜索 + 密集向量搜索),使用 RRF
resp = client.search( index="movies", retriever={ "rrf": { "retrievers": [ { "standard": { "query": { "sparse_vector": { "field": "plot_embedding", "inference_id": "my-elser-model", "query": "films that explore psychological depths" } } } }, { "standard": { "query": { "multi_match": { "query": "crime", "fields": [ "plot", "title" ] } } } }, { "knn": { "field": "vector", "query_vector": [ 10, 22, 77 ], "k": 10, "num_candidates": 10 } } ] } }, ) print(resp)
const response = await client.search({ index: "movies", retriever: { rrf: { retrievers: [ { standard: { query: { sparse_vector: { field: "plot_embedding", inference_id: "my-elser-model", query: "films that explore psychological depths", }, }, }, }, { standard: { query: { multi_match: { query: "crime", fields: ["plot", "title"], }, }, }, }, { knn: { field: "vector", query_vector: [10, 22, 77], k: 10, num_candidates: 10, }, }, ], }, }, }); console.log(response);
GET movies/_search { "retriever": { "rrf": { "retrievers": [ { "standard": { "query": { "sparse_vector": { "field": "plot_embedding", "inference_id": "my-elser-model", "query": "films that explore psychological depths" } } } }, { "standard": { "query": { "multi_match": { "query": "crime", "fields": [ "plot", "title" ] } } } }, { "knn": { "field": "vector", "query_vector": [10, 22, 77], "k": 10, "num_candidates": 10 } } ] } } }
文本相似度重排序检索器
编辑text_similarity_reranker
检索器使用 NLP 模型通过根据文档与查询的语义相似度对 top-k 文档进行重新排序来改进搜索结果。
有关语义重排序的高级概述,请参阅语义重排序。
先决条件
编辑要使用 text_similarity_reranker
,您必须首先使用 创建推理 API 为 rerank
任务设置推理端点。应使用可以计算文本相似度的机器学习模型设置端点。有关 Elasticsearch 支持的第三方文本相似度模型列表,请参阅Elastic NLP 模型参考。
您有以下选项
- 使用内置的 Elastic 重排序 交叉编码器模型,通过推理 API 的 Elasticsearch 服务。
- 使用 Cohere 重排序推理端点,任务类型为
rerank
。 - 使用 Google Vertex AI 推理端点,任务类型为
rerank
。 -
使用 Eland 将模型上传到 Elasticsearch,NLP 任务类型为
text_similarity
。- 然后使用
rerank
任务类型设置 Elasticsearch 服务推理端点。 - 有关分步指南,请参阅此页面上的示例。
- 然后使用
参数
编辑-
retriever
-
(必需,检索器)
生成要重新排序的初始 top 文档集的子检索器。
-
field
-
(必需,
string
)用于文本相似度比较的文档字段。此字段应包含将对照
inferenceText
进行评估的文本。 -
inference_id
-
(必需,
string
)使用推理 API 创建的推理端点的唯一标识符。
-
inference_text
-
(必需,
string
)用作相似度比较基础的文本片段。
-
rank_window_size
-
(可选,
int
)在重排序过程中要考虑的 top 文档数。默认为
10
。 -
min_score
-
(可选,
float
)为将文档包含在重排序结果中设置最小阈值分数。相似度分数低于此阈值的文档将被排除。请注意,分数计算因所使用的模型而异。
-
filter
-
(可选,查询对象或查询对象列表)
示例:Elastic 重排序
编辑此示例演示如何部署 Elastic 重排序模型并使用它通过 text_similarity_reranker
检索器对搜索结果进行重新排序。
请按照以下步骤操作
-
使用创建推理 API 为
rerank
任务创建推理端点。const response = await client.inference.put({ task_type: "rerank", inference_id: "my-elastic-rerank", inference_config: { service: "elasticsearch", service_settings: { model_id: ".rerank-v1", num_threads: 1, adaptive_allocations: { enabled: true, min_number_of_allocations: 1, max_number_of_allocations: 10, }, }, }, }); console.log(response);
PUT _inference/rerank/my-elastic-rerank { "service": "elasticsearch", "service_settings": { "model_id": ".rerank-v1", "num_threads": 1, "adaptive_allocations": { "enabled": true, "min_number_of_allocations": 1, "max_number_of_allocations": 10 } } }
自适应分配将启用,最小值为 1 个分配,最大值为 10 个分配。
-
定义一个
text_similarity_rerank
检索器const response = await client.search({ retriever: { text_similarity_reranker: { retriever: { standard: { query: { match: { text: "How often does the moon hide the sun?", }, }, }, }, field: "text", inference_id: "my-elastic-rerank", inference_text: "How often does the moon hide the sun?", rank_window_size: 100, min_score: 0.5, }, }, }); console.log(response);
POST _search { "retriever": { "text_similarity_reranker": { "retriever": { "standard": { "query": { "match": { "text": "How often does the moon hide the sun?" } } } }, "field": "text", "inference_id": "my-elastic-rerank", "inference_text": "How often does the moon hide the sun?", "rank_window_size": 100, "min_score": 0.5 } } }
示例:Cohere 重排序
编辑此示例通过使用 Cohere 重排序 API 对 top 文档进行重新排序来启用开箱即用的语义搜索。此方法无需为所有索引文档生成和存储嵌入。这需要一个为 rerank
任务类型设置的Cohere 重排序推理端点。
resp = client.search( index="index", retriever={ "text_similarity_reranker": { "retriever": { "standard": { "query": { "match_phrase": { "text": "landmark in Paris" } } } }, "field": "text", "inference_id": "my-cohere-rerank-model", "inference_text": "Most famous landmark in Paris", "rank_window_size": 100, "min_score": 0.5 } }, ) print(resp)
const response = await client.search({ index: "index", retriever: { text_similarity_reranker: { retriever: { standard: { query: { match_phrase: { text: "landmark in Paris", }, }, }, }, field: "text", inference_id: "my-cohere-rerank-model", inference_text: "Most famous landmark in Paris", rank_window_size: 100, min_score: 0.5, }, }, }); console.log(response);
GET /index/_search { "retriever": { "text_similarity_reranker": { "retriever": { "standard": { "query": { "match_phrase": { "text": "landmark in Paris" } } } }, "field": "text", "inference_id": "my-cohere-rerank-model", "inference_text": "Most famous landmark in Paris", "rank_window_size": 100, "min_score": 0.5 } } }
示例:使用 Hugging Face 模型进行语义重排序
编辑以下示例使用 Hugging Face 的 cross-encoder/ms-marco-MiniLM-L-6-v2
模型,根据语义相似度对搜索结果进行重新排序。必须使用 Eland 将模型上传到 Elasticsearch。
有关 Elasticsearch 支持的第三方文本相似度模型列表,请参阅Elastic NLP 模型参考。
请按照以下步骤加载模型并创建语义重排序器。
-
使用
pip
安装 Elandpython -m pip install eland[pytorch]
-
使用 Eland 将模型上传到 Elasticsearch。此示例假设您拥有 Elastic Cloud 部署和 API 密钥。有关更多身份验证选项,请参阅Eland 文档。
eland_import_hub_model \ --cloud-id $CLOUD_ID \ --es-api-key $ES_API_KEY \ --hub-model-id cross-encoder/ms-marco-MiniLM-L-6-v2 \ --task-type text_similarity \ --clear-previous \ --start
-
为
rerank
任务创建推理端点resp = client.inference.put( task_type="rerank", inference_id="my-msmarco-minilm-model", inference_config={ "service": "elasticsearch", "service_settings": { "num_allocations": 1, "num_threads": 1, "model_id": "cross-encoder__ms-marco-minilm-l-6-v2" } }, ) print(resp)
const response = await client.inference.put({ task_type: "rerank", inference_id: "my-msmarco-minilm-model", inference_config: { service: "elasticsearch", service_settings: { num_allocations: 1, num_threads: 1, model_id: "cross-encoder__ms-marco-minilm-l-6-v2", }, }, }); console.log(response);
PUT _inference/rerank/my-msmarco-minilm-model { "service": "elasticsearch", "service_settings": { "num_allocations": 1, "num_threads": 1, "model_id": "cross-encoder__ms-marco-minilm-l-6-v2" } }
-
定义一个
text_similarity_rerank
检索器。resp = client.search( index="movies", retriever={ "text_similarity_reranker": { "retriever": { "standard": { "query": { "match": { "genre": "drama" } } } }, "field": "plot", "inference_id": "my-msmarco-minilm-model", "inference_text": "films that explore psychological depths" } }, ) print(resp)
const response = await client.search({ index: "movies", retriever: { text_similarity_reranker: { retriever: { standard: { query: { match: { genre: "drama", }, }, }, }, field: "plot", inference_id: "my-msmarco-minilm-model", inference_text: "films that explore psychological depths", }, }, }); console.log(response);
POST movies/_search { "retriever": { "text_similarity_reranker": { "retriever": { "standard": { "query": { "match": { "genre": "drama" } } } }, "field": "plot", "inference_id": "my-msmarco-minilm-model", "inference_text": "films that explore psychological depths" } } }
此检索器使用标准的
match
查询在movie
索引中搜索标记为“drama”类型的电影。然后,它根据与inference_text
参数中的文本的语义相似度对结果进行重新排序,使用我们上传到 Elasticsearch 的模型。
查询规则检索器
编辑rule
检索器通过将上下文查询规则应用于特定查询,来固定或排除文档,从而实现对搜索结果的精细控制。此检索器具有与规则查询类似的功能,但可以与其他检索器开箱即用。
先决条件
编辑要使用 rule
检索器,您必须首先使用查询规则管理 API 创建一个或多个查询规则集。
参数
编辑示例:规则检索器
编辑此示例显示了在没有任何其他检索器的情况下执行的规则检索器。它运行由 retriever
定义的查询,并将来自 my-ruleset
的规则应用于返回的结果之上。
resp = client.search( index="movies", retriever={ "rule": { "match_criteria": { "query_string": "harry potter" }, "ruleset_ids": [ "my-ruleset" ], "retriever": { "standard": { "query": { "query_string": { "query": "harry potter" } } } } } }, ) print(resp)
const response = await client.search({ index: "movies", retriever: { rule: { match_criteria: { query_string: "harry potter", }, ruleset_ids: ["my-ruleset"], retriever: { standard: { query: { query_string: { query: "harry potter", }, }, }, }, }, }, }); console.log(response);
GET movies/_search { "retriever": { "rule": { "match_criteria": { "query_string": "harry potter" }, "ruleset_ids": [ "my-ruleset" ], "retriever": { "standard": { "query": { "query_string": { "query": "harry potter" } } } } } } }
示例:与 RRF 结合的规则检索器
编辑此示例展示了如何将 rule
检索器与其他重新排序检索器(例如 rrf 或 text_similarity_reranker)结合使用。
rule
检索器会将规则应用于从其定义的 retriever
或其任何子检索器返回的任何文档。这意味着为了获得最佳结果,rule
检索器应为最外层定义的检索器。将 rule
检索器作为子检索器嵌套在 rrf
或 text_similarity_reranker
等重新排序器下可能无法产生预期的结果。
resp = client.search( index="movies", retriever={ "rule": { "match_criteria": { "query_string": "harry potter" }, "ruleset_ids": [ "my-ruleset" ], "retriever": { "rrf": { "retrievers": [ { "standard": { "query": { "query_string": { "query": "sorcerer's stone" } } } }, { "standard": { "query": { "query_string": { "query": "chamber of secrets" } } } } ] } } } }, ) print(resp)
const response = await client.search({ index: "movies", retriever: { rule: { match_criteria: { query_string: "harry potter", }, ruleset_ids: ["my-ruleset"], retriever: { rrf: { retrievers: [ { standard: { query: { query_string: { query: "sorcerer's stone", }, }, }, }, { standard: { query: { query_string: { query: "chamber of secrets", }, }, }, }, ], }, }, }, }, }); console.log(response);
GET movies/_search { "retriever": { "rule": { "match_criteria": { "query_string": "harry potter" }, "ruleset_ids": [ "my-ruleset" ], "retriever": { "rrf": { "retrievers": [ { "standard": { "query": { "query_string": { "query": "sorcerer's stone" } } } }, { "standard": { "query": { "query_string": { "query": "chamber of secrets" } } } } ] } } } } }
常见用法指南
编辑将 from
和 size
与检索器树一起使用
编辑from
和 size
参数作为通用搜索 API 的一部分全局提供。它们应用于检索器树中的所有检索器,除非特定检索器使用不同的参数(例如 rank_window_size
)覆盖 size
参数。但是,最终的搜索命中始终限制为 size
。
将聚合与检索器树一起使用
编辑聚合作为搜索请求的一部分全局指定。用于聚合的查询是所有叶检索器的组合,作为布尔查询中的 should
子句。
指定检索器时对搜索参数的限制
编辑当检索器作为搜索的一部分指定时,以下元素不允许位于顶层