Indexer les champs d'un StructArray

Créez des index sur les sous-champs StructArray avant d’exécuter une recherche vectorielle ou d’accélérer un filtrage scalaire. Pour un champ StructArray, la cible de l’index est un chemin de sous-champ, tel que chunks[emb_list_vector], chunks[emb] ou chunks[section].

Cette page utilise la collection tech_articles issue de la section Créer un champ StructArray. Le champ StructArray chunks contient des sous-champs scalaires pour le filtrage et des sous-champs vectoriels pour la recherche.

Avant de commencer

Assurez-vous que le schéma de la collection contient déjà le champ StructArray « chunks » et que des données y ont été insérées.

Chemin d’accès au sous-champTypeObjectif de l’index
chunks[emb_list_vector]FLOAT_VECTORRecherche dans EmbeddingList à l’aide des métriques d’ MAX_SIM*.
chunks[emb]FLOAT_VECTORRecherche au niveau des éléments avec des métriques vectorielles classiques.
chunks[section]VARCHARFiltrage catégoriel.
chunks[quality_score]FLOATFiltrage numérique et prédicats de type « plage ».
chunks[has_code]BOOLFiltrage booléen.

Un champ vectoriel ou un sous-champ vectoriel n’accepte qu’un seul index. Si vous avez besoin à la fois d’une recherche EmbeddingList et d’une recherche au niveau des éléments, créez deux sous-champs vectoriels distincts et indexez-les séparément. Sur cette page, chunks[emb_list_vector] est indexé pour la recherche EmbeddingList, et chunks[emb] est indexé pour la recherche au niveau des éléments.

Choisissez les index

Utilisez le mode de recherche pour choisir la famille de métriques vectorielles.

Objectif de la recherche ou du filtrageChemin cibleQue choisir
Recherche dans EmbeddingListchunks[emb_list_vector]Une famille de métriques « MAX_SIM* ».
Recherche vectorielle au niveau des élémentschunks[emb]Une famille de métriques vectorielles classiques, telles que COSINE, IP ou L2.
Filtrer par chaîne de caractères ou par catégoriechunks[section]Un index scalaire pris en charge par votre cible.
Filtrer par plage numériquechunks[quality_score], chunks[page]Un index scalaire pris en charge par votre cible.
Filtrer par valeur booléennechunks[has_code]Un index scalaire pris en charge par votre cible.

La recherche EmbeddingList traite les vecteurs d’un sous-champ vectoriel StructArray comme une liste d’intégration et renvoie des résultats au niveau de l’entité. La recherche au niveau des éléments explore chaque élément Struct indépendamment et peut renvoyer l’offset de l’élément correspondant.

Créer des index vectoriels

L'exemple suivant crée deux index vectoriels. Le premier index utilise une métrique « MAX_SIM* » pour la recherche EmbeddingList. Le second index utilise une métrique vectorielle standard pour la recherche au niveau des éléments.

from pymilvus import MilvusClient

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

index_params = client.prepare_index_params()

# Index for EmbeddingList search.
index_params.add_index(
    field_name="chunks[emb_list_vector]",
    index_name="chunks_emb_list_max_sim",
    index_type="HNSW",
    metric_type="MAX_SIM_COSINE",
    params={
        "M": 16,
        "efConstruction": 200,
    },
)

# Index for element-level search.
index_params.add_index(
    field_name="chunks[emb]",
    index_name="chunks_emb_cosine",
    index_type="HNSW",
    metric_type="COSINE",
    params={
        "M": 16,
        "efConstruction": 200,
    },
)

client.create_index(
    collection_name="tech_articles",
    index_params=index_params,
)

Avertissement Ne créez pas d’index « MAX_SIM* » et d’index à métrique vectorielle standard sur le même sous-champ vectoriel. Si les deux modes de recherche sont nécessaires, écrivez les vecteurs dans deux sous-champs vectoriels distincts et créez un index sur chaque sous-champ.

Créer des index scalaires

Créez des index scalaires sur les sous-champs scalaires de StructArray lorsque vous les utilisez dans des filtres. Utilisez la même syntaxe de chemin d’accès que pour « structArray[subfield] ».

index_params = client.prepare_index_params()

index_params.add_index(
    field_name="chunks[section]",
    index_name="chunks_section_inverted",
    index_type="INVERTED",
)

index_params.add_index(
    field_name="chunks[has_code]",
    index_name="chunks_has_code_inverted",
    index_type="INVERTED",
)

index_params.add_index(
    field_name="chunks[quality_score]",
    index_name="chunks_quality_score_sort",
    index_type="STL_SORT",
)

index_params.add_index(
    field_name="chunks[page]",
    index_name="chunks_page_sort",
    index_type="STL_SORT",
)

client.create_index(
    collection_name="tech_articles",
    index_params=index_params,
)

Les index scalaires sont facultatifs mais utiles lorsque les sous-champs scalaires de StructArray apparaissent fréquemment dans des filtres, tels que element_filter(chunks, $[quality_score] > 0.9) ou MATCH_ANY(chunks, $[section] == "index").

Compatibilité des métriques d’index

Utilisez les tableaux suivants pour choisir un type d’index et un type de métrique pour un sous-champ vectoriel de StructArray. Commencez par la cible, puis choisissez la famille de métriques en fonction du mode de recherche.

Choisissez un type d’index Milvus et un type de métrique à partir des tableaux de compatibilité suivants.

La recherche EmbeddingList utilise les métriques de type « MAX_SIM* ». Elle traite les vecteurs d’un sous-champ vectoriel StructArray comme une liste d’embeddings et renvoie des résultats au niveau des entités.

Type de données du sous-champ vectorielType d’indexType de métrique
FLOAT_VECTOR, FLOAT16_VECTOR, BFLOAT16_VECTORIVF_FLAT, IVF_FLAT_CC, HNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQ, DISKANNMAX_SIM, MAX_SIM_COSINE, MAX_SIM_IP, MAX_SIM_L2
INT8_VECTORHNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQMAX_SIM, MAX_SIM_COSINE, MAX_SIM_IP, MAX_SIM_L2
BINARY_VECTORHNSWMAX_SIM_HAMMING, MAX_SIM_JACCARD

La recherche au niveau des éléments utilise des métriques vectorielles classiques. Elle explore chaque élément de la structure indépendamment et peut renvoyer l'offset de l'élément correspondant.

Type de données des sous-champs vectorielsType d’indexType de métrique
FLOAT_VECTOR, FLOAT16_VECTOR, BFLOAT16_VECTORFLAT, IVF_FLAT, IVF_FLAT_CC, IVF_SQ8, IVF_SQ_CC, IVF_PQ, SCANN, IVF_RABITQ, IVF_RABITQ_FASTSCAN, HNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQ, DISKANNL2, IP, COSINE
INT8_VECTORHNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQL2, IP, COSINE
BINARY_VECTORHNSWHAMMING, JACCARD
BINARY_VECTORBIN_FLATHAMMING, JACCARD, SUBSTRUCTURE, SUPERSTRUCTURE, MHJACCARD
BINARY_VECTORBIN_IVF_FLATHAMMING, JACCARD

Pour obtenir une assistance spécifique à une version et connaître les autres limites, consultez la section Limites de StructArray.

Vérification des index

Après avoir créé des index, décrivez les index de la collection ou de la liste pour vérifier que les chemins d’accès aux sous-champs attendus sont bien indexés.

indexes = client.list_indexes(
    collection_name="tech_articles",
)

print(indexes)

Vous pouvez également décrire un index spécifique si votre version du SDK expose des API de description d’index.

index = client.describe_index(
    collection_name="tech_articles",
    index_name="chunks_emb_cosine",
)

print(index)

Règles d’indexation

RègleExplication
Utilisez la syntaxe de chemin d’accès pour les index de sous-champs.chunks[emb] d'index , et non emb ou chunks.emb.
Un sous-champ vectoriel n'accepte qu'un seul index.Utilisez des sous-champs vectoriels distincts si vous avez besoin de familles de métriques différentes.
Utilisez les métriques de type « MAX_SIM* » pour la recherche EmbeddingList.Les données de requête EmbeddingList nécessitent un index créé avec une métrique de type « MAX_SIM* ».
Utilisez des métriques vectorielles standard pour la recherche au niveau des éléments.La recherche au niveau des éléments utilise des données de requête vectorielles standard et des métriques telles que « COSINE », « IP » ou « L2 ».
Indexez les sous-champs scalaires qui apparaissent dans les filtres.Utilisez les types d’index scalaires pris en charge par votre cible.
Gardez à l’esprit les limites des champs vectoriels.Le nombre total de champs vectoriels et de sous-champs vectoriels est limité. Consultez la section « Limites de StructArray » avant d’ajouter un grand nombre de sous-champs vectoriels.

Erreurs courantes

  • Créer un index sur « chunks.emb » au lieu de « chunks[emb] ».

  • Créer uniquement un index MAX_SIM*, puis tenter d'effectuer une recherche au niveau des éléments sur ce même sous-champ.

  • Créer uniquement un index vectoriel standard, puis tenter d’effectuer une recherche EmbeddingList sur ce même sous-champ.

  • Réutiliser un sous-champ vectoriel à la fois pour les métriques « MAX_SIM* » et les métriques vectorielles classiques.

  • Oublier les index scalaires pour les filtres StructArray très utilisés.

  • L'indexation d'un sous-champ StructArray qui n'existe pas dans le schéma Struct.

Étapes suivantes

  1. Pour effectuer une recherche EmbeddingList au niveau de l’entité ou une recherche vectorielle au niveau de l’élément, consultez la section « Recherche vectorielle de base avec StructArray ».

  2. Pour filtrer les sous-champs scalaires StructArray lors d’une recherche, consultez la section « Recherche filtrée avec StructArray ».

  3. Pour connaître les limites relatives aux index et aux métriques, consultez la section « Limites de StructArray ».