Insérer des données dans les champs StructArray

Insérez des données dans un champ StructArray lorsque chaque entité contient une liste ordonnée d’éléments structurés. Dans la charge utile d’insertion, un champ StructArray est représenté sous la forme d’un tableau d’objets. Chaque objet représente un élément Struct et utilise les noms des sous-champs Struct définis dans le schéma de la collection.

Cette page utilise la collection « tech_articles » ( Créer un champ StructArray) issue de la section « Créer un champ StructArray ». Chaque entité est un article technique, et le champ « chunks » stocke des segments d’article sous forme d’éléments Struct.

Avant de commencer

Assurez-vous que le schéma de collection contient déjà le champ StructArray « chunks ».

ChampTypeValeur d’insertion
doc_idINT64ID de l'article.
titleVARCHARTitre de l'article.
categoryVARCHARCatégorie de l'article.
title_vectorFLOAT_VECTORIntégration au niveau de l'article.
chunksARRAYUne liste d'objets « chunk ».

Chaque objet de l'chunks e doit respecter le schéma Struct.

Sous-champTypeValeur à insérer
textVARCHARTexte du chunk.
sectionVARCHARNom de la section, tel que index, search ou filter.
pageINT64Numéro de page ou position logique.
quality_scoreFLOATNote au niveau du bloc.
has_codeBOOLIndique si le bloc contient du code.
emb_list_vectorFLOAT_VECTORVecteur généré pour la recherche EmbeddingList.
embFLOAT_VECTORVecteur créé pour la recherche au niveau des éléments.

Dans une charge utile d’insertion, « chunks » est un champ standard dont la valeur est un tableau d’objets Struct. À l’intérieur de chaque objet, utilisez des noms de sous-champs tels que « text » et « emb ». N’utilisez la syntaxe de chemin d’accès, telle que « chunks[text] » ou « chunks[emb] », qu’après l’insertion, lorsque vous créez des index, effectuez des recherches, construisez des filtres ou spécifiez des champs de sortie.

Comprendre la structure de la charge utile d’insertion

La valeur ` chunks ` est un tableau d’éléments de type `Struct`. Chaque élément est un objet dont les clés sont des noms de sous-champs.

{
  "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_vector et emb sont des sous-champs vectoriels distincts, car ils prennent en charge des modes de recherche différents. La recherche EmbeddingList traite tous les vecteurs d’un champ StructArray comme une seule liste d’embeddings et renvoie des résultats au niveau de l’entité avec des métriques de type « MAX_SIM* ». La recherche au niveau des éléments explore chaque élément Struct indépendamment et peut renvoyer l’offset de l’élément correspondant. Dans cet exemple, les mêmes valeurs vectorielles sont stockées dans les deux champs par souci de simplicité. Dans une application de production, vous pouvez stocker les mêmes représentations dans les deux sous-champs lorsque les deux modes de recherche utilisent la même représentation par blocs, ou stocker des représentations différentes lorsque les deux modes de recherche utilisent des représentations différentes.

Insérer des lignes

Utilisez ` client.insert() ` pour insérer des lignes contenant des valeurs de type `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)

Insertion dans des champs StructArray pouvant être nuls

Si le champ ` chunks ` est non nul, une entité peut définir l’intégralité du champ ` chunks ` sur `null`. En Python, utilisez ` None ` pour représenter une valeur `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,
        }
    ],
)

Lorsqu’un champ StructArray pouvant prendre la valeur null contient une valeur StructArray valide, tous les sous-champs de cette valeur doivent soit être nuls, soit avoir des valeurs valides. L’insertion d’une entité dont certains sous-champs sont définis sur null et d’autres sur des valeurs valides entraîne une erreur.

Avertissement Les champs StructArray pouvant prendre la valeur null ne sont disponibles que dans Milvus v3.0.x. Si vous ajoutez dynamiquement un champ StructArray à une collection existante, le champ ajouté doit pouvoir prendre la valeur null, et les entités existantes doivent renvoyer « null » pour le nouveau champ sur l’ensemble de ses sous-champs.

Valider les données insérées

Vous pouvez interroger la collection et renvoyer le champ StructArray ou les sous-champs sélectionnés.

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)

N’utilisez les chemins d’accès aux champs StructArray, tels que chunks[text], que lors d’une requête, d’une recherche, d’un filtrage ou de la création d’index. Les charges utiles d’insertion doivent toujours utiliser des objets imbriqués sous chunks.

Règles d’insertion

RègleExplication
Utilisez un tableau d’objets pour un champ StructArray.La valeur de chunks est une liste, et chaque élément de cette liste est un élément Struct.
Utilisez des noms de sous-champs à l'intérieur de chaque élément Struct.Insérez « {"text": "...", "emb": [...]} » dans « chunks », et non dans « {"chunks[text]": "..."} ».
Respectez le schéma de la structure.Chaque élément Struct doit utiliser les sous-champs définis dans le schéma Struct.
Respectez les dimensions des vecteurs.Les valeurs des vecteurs doivent correspondre aux dim s configurées pour leurs sous-champs vectoriels.
Respecter l’ max_capacity.Le nombre d’éléments Struct dans une entité ne doit pas dépasser l’ max_capacity du champ StructArray.
Utilisez des sous-champs vectoriels distincts pour les différents modes de recherche.Si la recherche EmbeddingList et la recherche au niveau des éléments sont toutes deux requises, écrivez les valeurs vectorielles dans les deux sous-champs vectoriels.
N’utilisez la valeur « null » que lorsque le champ peut être nul.Les champs StructArray non nuls nécessitent des valeurs StructArray valides.

Erreurs courantes

  • Utilisation de chemins de champ tels que « chunks[text] » dans les charges utiles d’insertion.

  • Omission de sous-champs obligatoires dans un élément Struct.

  • Insérer des vecteurs dont la dimension est incorrecte.

  • Insérer plus d’éléments Struct que ne le permet max_capacity.

  • Définir un seul sous-champ sur « null » alors que d’autres sous-champs de la même valeur StructArray sont valides.

  • Écriture de vecteurs uniquement dans ` emb_list_vector `, puis tentative d’exécution d’une recherche au niveau des éléments sur ` chunks[emb]`.

  • Écriture de vecteurs uniquement dans « emb », puis tentative d’exécution d’une recherche EmbeddingList sur « chunks[emb_list_vector] ».

Étapes suivantes

  1. Pour créer des index pour les sous-champs chunks[emb_list_vector], chunks[emb] et scalaires, consultez la section Indexer les champs StructArray.

  2. Pour effectuer une recherche dans les sous-champs vectoriels de StructArray, consultez la section « Recherche vectorielle de base avec StructArray ».

  3. Pour en savoir plus sur le comportement des valeurs nulles et les limitations spécifiques à chaque version, consultez la section « Limites de StructArray ».