使用 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常规向量度量,例如COSINEIPL2
一个匹配结果代表什么一个匹配的实体,其 StructArray 向量子场与查询嵌入列表相似。StructArray 字段内的匹配 Struct 元素。
结果粒度实体级别。Struct 元素级别。
偏移量不适用。标识返回时匹配的结构元素的零基位置。
典型用法ColBERT、ColPali 及其他后期交互检索模式。块级、段落级、片段级、补丁级或事实级检索。

当查询本身包含多个向量,且目标 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 搜索会返回一个特定的元素偏移量,但实际返回的是实体级别的匹配结果。

  • 将同一个向量子场同时用于两种搜索模式。应使用独立的向量子场,因为每个向量子场仅支持一种索引。

后续步骤

  1. 若要通过标量条件限制元素级搜索,请参阅《使用 StructArray 进行过滤搜索》。

  2. 若要按分数或距离阈值进行搜索,请参阅《使用 StructArray 进行范围搜索》。

  3. 若要在元素级搜索后,为每个父实体最多返回一个结果,请参阅《使用 StructArray 进行分组搜索》。

  4. 若要将 StructArray 搜索与其他向量搜索结合使用,请参阅《使用 StructArray 进行混合搜索》。

  5. 如需查看支持的数据类型、度量、过滤器以及特定版本的限制,请参阅《StructArray 限制》

翻译自DeepL

想要更快、更简单、更好用的 Milvus SaaS服务 ?

Zilliz Cloud是基于Milvus的全托管向量数据库,拥有更高性能,更易扩展,以及卓越性价比

免费试用 Zilliz Cloud
反馈

此页对您是否有帮助?