将数据插入 StructArray 字段

当每个实体包含一个有序的结构化元素列表时,可将数据插入到 StructArray 字段中。在插入有效载荷中,StructArray 字段表示为一个对象数组。每个对象代表一个 Struct 元素,并使用 Collection 模式中定义的 Struct 子字段名称。

本页使用《创建 StructArray 字段》中的tech_articles Collection。每个实体都是一篇技术文章,而chunks 字段将文章片段作为 Struct 元素进行存储。

开始之前

请确保Collection Schema中已包含chunks StructArray字段。

字段类型插入值
doc_idINT64文章 ID。
titleVARCHAR文章标题。
categoryVARCHAR文章分类。
title_vectorFLOAT_VECTOR文章级Embeddings。
chunksARRAY一段对象列表。

chunks 中的每个对象都必须遵循 Struct Schema。

子字段类型插入值
textVARCHAR块文本。
sectionVARCHAR部分名称,例如indexsearchfilter
pageINT64页码或逻辑位置。
quality_scoreFLOAT片段级评分。
has_codeBOOL该片段是否包含代码。
emb_list_vectorFLOAT_VECTOR为 EmbeddingList 搜索编写的向量。
embFLOAT_VECTOR为元素级搜索编写的向量。

在插入有效载荷中,chunks 是一个常规字段,其值为一个Struct对象数组。在每个对象内部,请使用textemb 等子字段名称。仅在插入完成后创建索引、运行搜索、构建过滤器或指定输出字段时,才使用chunks[text]chunks[emb] 等路径语法。

了解插入有效载荷的结构

chunks 的值是一个由 Struct 元素组成的数组。每个元素都是一个对象,其键为子字段名称。

{
  "doc_id": 1,
  "title": "StructArray indexing patterns",
  "category": "index",
  "title_vector": [0.12, 0.08, 0.32, 0.48],
  "chunks": [
    {
      "text": "Create one index for each vector subfield.",
      "section": "index",
      "page": 1,
      "quality_score": 0.96,
      "has_code": false,
      "emb_list_vector": [0.10, 0.20, 0.30, 0.40],
      "emb": [0.10, 0.20, 0.30, 0.40]
    },
    {
      "text": "Use MAX_SIM metrics for EmbeddingList search.",
      "section": "index",
      "page": 2,
      "quality_score": 0.91,
      "has_code": true,
      "emb_list_vector": [0.16, 0.24, 0.35, 0.45],
      "emb": [0.16, 0.24, 0.35, 0.45]
    }
  ]
}

emb_list_vectoremb 是独立的向量子字段,因为它们支持不同的搜索模式。EmbeddingList 搜索将 StructArray 字段中的所有向量视为一个嵌入列表,并返回带有MAX_SIM* 指标的实体级结果。元素级搜索则独立搜索每个 Struct 元素,并可返回匹配元素的偏移量。为简化起见,本示例在两个字段中存储了相同的向量值。 在生产应用中,当两种搜索模式使用相同的块Embeddings时,可以在这两个子字段中存储相同的Embeddings;当两种搜索模式使用不同的表示形式时,则可以存储不同的Embeddings。

插入行

使用 `client.insert() ` 插入包含 StructArray 值的行。

from pymilvus import MilvusClient

client = MilvusClient(
    uri="http://localhost:19530",
    token="root:Milvus",
)

data = [
    {
        "doc_id": 1,
        "title": "StructArray indexing patterns",
        "category": "index",
        "title_vector": [0.12, 0.08, 0.32, 0.48],
        "chunks": [
            {
                "text": "Create one index for each vector subfield.",
                "section": "index",
                "page": 1,
                "quality_score": 0.96,
                "has_code": False,
                "emb_list_vector": [0.10, 0.20, 0.30, 0.40],
                "emb": [0.10, 0.20, 0.30, 0.40],
            },
            {
                "text": "Use MAX_SIM metrics for EmbeddingList search.",
                "section": "index",
                "page": 2,
                "quality_score": 0.91,
                "has_code": True,
                "emb_list_vector": [0.16, 0.24, 0.35, 0.45],
                "emb": [0.16, 0.24, 0.35, 0.45],
            },
        ],
    },
    {
        "doc_id": 2,
        "title": "Filtered StructArray search",
        "category": "filter",
        "title_vector": [0.20, 0.18, 0.22, 0.40],
        "chunks": [
            {
                "text": "Use element_filter to match scalar conditions within the same Struct element.",
                "section": "filter",
                "page": 1,
                "quality_score": 0.93,
                "has_code": True,
                "emb_list_vector": [0.21, 0.18, 0.33, 0.44],
                "emb": [0.21, 0.18, 0.33, 0.44],
            },
            {
                "text": "MATCH_LEAST checks how many elements satisfy a predicate.",
                "section": "filter",
                "page": 2,
                "quality_score": 0.88,
                "has_code": False,
                "emb_list_vector": [0.24, 0.22, 0.31, 0.39],
                "emb": [0.24, 0.22, 0.31, 0.39],
            },
        ],
    },
    {
        "doc_id": 3,
        "title": "Element-level search with offsets",
        "category": "search",
        "title_vector": [0.33, 0.11, 0.29, 0.37],
        "chunks": [
            {
                "text": "Element-level search can return the offset of the matched Struct element.",
                "section": "search",
                "page": 1,
                "quality_score": 0.95,
                "has_code": False,
                "emb_list_vector": [0.32, 0.14, 0.28, 0.41],
                "emb": [0.32, 0.14, 0.28, 0.41],
            }
        ],
    },
]

result = client.insert(
    collection_name="tech_articles",
    data=data,
)

print(result)

插入可为空的 StructArray 字段

如果chunks 字段是可空的,则实体可以将整个chunks 字段设置为null。在Python中,使用None 来表示null值。

client.insert(
    collection_name="tech_articles",
    data=[
        {
            "doc_id": 10,
            "title": "Article without chunks yet",
            "category": "draft",
            "title_vector": [0.05, 0.10, 0.15, 0.20],
            "chunks": None,
        }
    ],
)

当可为空的 StructArray 字段包含一个有效的 StructArray 值时,该值中的所有子字段应均为空或具有有效值。若插入的实体中部分子字段设为空而其他子字段设为有效值,则会引发错误。

警告 可为空的 StructArray 字段仅在 Milvus v3.0.x 中可用。若向现有 Collection 动态添加 StructArray 字段,则该新增字段必须为可为空类型,且现有实体针对该新字段的所有子字段均应返回 `null `。

验证插入的数据

您可以查询 Collection 并返回 StructArray 字段或选定的子字段。

rows = client.query(
    collection_name="tech_articles",
    filter="doc_id in [1, 2, 3]",
    output_fields=[
        "doc_id",
        "title",
        "chunks[text]",
        "chunks[section]",
        "chunks[quality_score]",
    ],
)

for row in rows:
    print(row)

仅在查询、搜索、过滤或创建索引时使用 StructArray 字段路径(例如chunks[text] )。插入有效负载时仍应使用chunks 下的嵌套对象。

插入规则

规则说明
对于 StructArray 字段,请使用对象数组。chunks 的值是一个列表,列表中的每个项目都是一个 Struct 元素。
在每个 Struct 元素内部使用子字段名称。{"text": "...", "emb": [...]} 插入chunks 中,而非{"chunks[text]": "..."} 中。
需符合 Struct Schema。每个 Struct 元素必须使用 Struct Schema 中定义的子字段。
向量维度必须匹配。向量值必须与为其向量子字段配置的dim 相匹配。
遵守max_capacity一个实体中的 Struct 元素数量不得超过 StructArray 字段的max_capacity
针对不同的搜索模式,请使用单独的向量子场。如果同时需要 EmbeddingList 搜索和元素级搜索,请将向量值写入两个向量子字段。
仅当字段允许为空时,才使用null非可空的 StructArray 字段需要有效的 StructArray 值。

常见错误

  • 在插入有效载荷中使用诸如chunks[text] 之类的字段路径。

  • 从 Struct 元素中省略必需的子字段。

  • 插入维度错误的向量。

  • 插入的 Struct 元素数量超过了max_capacity 允许的数量。

  • 仅将一个子字段设置为null ,而同一StructArray值中的其他子字段却有效。

  • 仅将向量写入emb_list_vector ,随后尝试在chunks[emb] 上执行元素级搜索。

  • 仅将向量写入emb ,随后尝试在chunks[emb_list_vector] 上执行EmbeddingList搜索。

后续步骤

  1. 要为chunks[emb_list_vector]chunks[emb] 以及标量子字段创建索引,请参阅《索引 StructArray 字段》。

  2. 要搜索 StructArray 向量子字段,请参阅《使用 StructArray 进行基本向量搜索》。

  3. 要了解可为空行为和特定版本的限制,请参阅《StructArray 限制》。

翻译自DeepL

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

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

免费试用 Zilliz Cloud
反馈

此页对您是否有帮助?