使用 StructArray 进行基础向量搜索
使用本页面可在 StructArray 字段内的向量子字段上执行向量搜索。StructArray 支持两种基本的向量搜索模式:嵌入列表搜索(对存储在每个实体中的嵌入列表进行评分)和元素级搜索(独立搜索每个 Struct 元素)。
本页面使用“创建 StructArray 字段”中的tech_articles Collection。该 Collection 包含一个名为chunks的 StructArray 字段。每个块包含文本、标量元数据、一个名为emb_list_vector 的向量字段(带有用于嵌入列表搜索的索引),以及一个名为emb 的向量字段(带有用于元素级搜索的索引)。
开始之前
请确保Collection Schema、数据和索引已准备就绪。
| 要求 | 准备位置 |
|---|---|
创建一个 StructArray 字段,例如chunks 。 | 创建 StructArray 字段 |
插入其chunks 字段包含Struct对象的实体。 | 将数据插入 StructArray 字段 |
在chunks[emb_list_vector] 上为EmbeddingList搜索创建一个MAX_SIM* 索引。 | 为 StructArray 字段建立索引 |
在chunks[emb] 上创建常规向量度量索引,用于元素级搜索。 | 为 StructArray 字段建立索引 |
警告
一个向量字段或向量子字段只能接受一个索引。如果您同时需要 EmbeddingList 搜索和元素级搜索,请创建两个独立的向量子字段。在此页面中,chunks[emb_list_vector] 被索引用于 EmbeddingList 搜索,而chunks[emb] 被索引用于元素级搜索。
选择搜索模式
| 方面 | EmbeddingList 搜索 | 元素级搜索 |
|---|---|---|
| 目标子字段 | chunks[emb_list_vector] | chunks[emb] |
| 查询数据 | 一个包含一个或多个向量的嵌入列表。 | 一个常规向量。 |
| 度量族 | MAX_SIM*,例如MAX_SIM_COSINE 。 | 常规向量度量,例如COSINE 、IP 或L2 。 |
| 一个匹配结果代表什么 | 一个匹配的实体,其 StructArray 向量子场与查询嵌入列表相似。 | StructArray 字段内的匹配 Struct 元素。 |
| 结果粒度 | 实体级别。 | Struct 元素级别。 |
| 偏移量 | 不适用。 | 标识返回时匹配的结构元素的零基位置。 |
| 典型用法 | ColBERT、ColPali 及其他后期交互检索模式。 | 块级、段落级、片段级、补丁级或事实级检索。 |
运行 EmbeddingList 搜索
当查询本身包含多个向量,且目标 StructArray 向量子字段使用MAX_SIM* 度量进行索引时,请使用 EmbeddingList 搜索。结果为实体级匹配。
from pymilvus import MilvusClient
from pymilvus.client.embedding_list import EmbeddingList
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus",
)
query = EmbeddingList()
query.add([0.12, 0.21, 0.32, 0.44])
query.add([0.18, 0.23, 0.29, 0.36])
results = client.search(
collection_name="tech_articles",
data=[query],
anns_field="chunks[emb_list_vector]",
limit=3,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
],
)
for hits in results:
for hit in hits:
print(hit["id"], hit["distance"], hit["entity"])
在此搜索模式下,limit 控制每个查询返回的实体数量。输出可能包含 StructArray 子字段,但命中结果本身代表匹配的父实体,而非某个特定的 Struct 元素。
有关完整的 ColBERT 或 ColPali 风格操作指南,请参阅《使用 Embeddings 列表进行搜索》。本页面仅介绍 StructArray 的基本搜索行为。
运行元素级搜索
当每个 Struct 元素应独立参与向量搜索时,请使用元素级搜索。查询是一个常规向量,且目标向量子字段必须使用常规向量度量进行索引。
query_vector = [0.19, 0.24, 0.30, 0.37]
results = client.search(
collection_name="tech_articles",
data=[query_vector],
anns_field="chunks[emb]",
limit=5,
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
"chunks[page]",
"chunks[quality_score]",
],
)
for hits in results:
for hit in hits:
print(
"doc_id:", hit["id"],
"distance:", hit["distance"],
"offset:", hit.get("offset"),
"entity:", hit["entity"],
)
在元素级搜索中,每个命中结果代表一个匹配的 Struct 元素。offset 值是该元素在 StructArray 字段中的从零开始的索引位置。如果多个 Struct 元素与查询匹配,同一实体可能会出现多次。limit 值适用于元素命中结果,而非唯一的父实体。
解读结果
| 结果项 | EmbeddingList 搜索 | 元素级搜索 |
|---|---|---|
id | 匹配实体的主键。 | 包含匹配的 Struct 元素的实体的主键。 |
distance 或得分 | 查询Embeddings列表与存储的Embeddings列表之间的得分或距离。 | 查询向量与匹配的 Struct 元素向量之间的得分或距离。 |
offset | 不适用。 | 返回时匹配的 Struct 元素的从零开始的索引位置。 |
| 重复的主键 | 由于结果是实体级别的,因此单个查询中不会出现这种情况。 | 可能出现,因为同一实体中的多个 Struct 元素可能会匹配。 |
| 请求的 StructArray 输出字段 | 从匹配的实体中返回。 | 将根据目标 API 和 SDK 支持的元素级命中结构进行返回。 |
常见错误
使用
chunks.emb代替必需的子字段路径语法chunks[emb]。对使用常规向量度量进行索引的向量子字段使用 EmbeddingList 查询。
对使用
MAX_SIM*度量进行索引的向量字段使用常规向量查询。期望元素级搜索
limit返回相应数量的唯一父实体。其实它返回的是元素匹配结果。预期 EmbeddingList 搜索会返回一个特定的元素偏移量,但实际返回的是实体级别的匹配结果。
将同一个向量子场同时用于两种搜索模式。应使用独立的向量子场,因为每个向量子场仅支持一种索引。
后续步骤
若要通过标量条件限制元素级搜索,请参阅《使用 StructArray 进行过滤搜索》。
若要按分数或距离阈值进行搜索,请参阅《使用 StructArray 进行范围搜索》。
若要在元素级搜索后,为每个父实体最多返回一个结果,请参阅《使用 StructArray 进行分组搜索》。
若要将 StructArray 搜索与其他向量搜索结合使用,请参阅《使用 StructArray 进行混合搜索》。
如需查看支持的数据类型、度量、过滤器以及特定版本的限制,请参阅《StructArray 限制》。