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-champ | Type | Objectif de l’index |
|---|---|---|
chunks[emb_list_vector] | FLOAT_VECTOR | Recherche dans EmbeddingList à l’aide des métriques d’ MAX_SIM*. |
chunks[emb] | FLOAT_VECTOR | Recherche au niveau des éléments avec des métriques vectorielles classiques. |
chunks[section] | VARCHAR | Filtrage catégoriel. |
chunks[quality_score] | FLOAT | Filtrage numérique et prédicats de type « plage ». |
chunks[has_code] | BOOL | Filtrage 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 filtrage | Chemin cible | Que choisir |
|---|---|---|
| Recherche dans EmbeddingList | chunks[emb_list_vector] | Une famille de métriques « MAX_SIM* ». |
| Recherche vectorielle au niveau des éléments | chunks[emb] | Une famille de métriques vectorielles classiques, telles que COSINE, IP ou L2. |
| Filtrer par chaîne de caractères ou par catégorie | chunks[section] | Un index scalaire pris en charge par votre cible. |
| Filtrer par plage numérique | chunks[quality_score], chunks[page] | Un index scalaire pris en charge par votre cible. |
| Filtrer par valeur booléenne | chunks[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.
Recherche EmbeddingList
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 vectoriel | Type d’index | Type de métrique |
|---|---|---|
FLOAT_VECTOR, FLOAT16_VECTOR, BFLOAT16_VECTOR | IVF_FLAT, IVF_FLAT_CC, HNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQ, DISKANN | MAX_SIM, MAX_SIM_COSINE, MAX_SIM_IP, MAX_SIM_L2 |
INT8_VECTOR | HNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQ | MAX_SIM, MAX_SIM_COSINE, MAX_SIM_IP, MAX_SIM_L2 |
BINARY_VECTOR | HNSW | MAX_SIM_HAMMING, MAX_SIM_JACCARD |
Recherche au niveau des éléments
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 vectoriels | Type d’index | Type de métrique |
|---|---|---|
FLOAT_VECTOR, FLOAT16_VECTOR, BFLOAT16_VECTOR | FLAT, 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, DISKANN | L2, IP, COSINE |
INT8_VECTOR | HNSW, HNSW_SQ, HNSW_PQ, HNSW_PRQ | L2, IP, COSINE |
BINARY_VECTOR | HNSW | HAMMING, JACCARD |
BINARY_VECTOR | BIN_FLAT | HAMMING, JACCARD, SUBSTRUCTURE, SUPERSTRUCTURE, MHJACCARD |
BINARY_VECTOR | BIN_IVF_FLAT | HAMMING, 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ègle | Explication |
|---|---|
| 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
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 ».
Pour filtrer les sous-champs scalaires StructArray lors d’une recherche, consultez la section « Recherche filtrée avec StructArray ».
Pour connaître les limites relatives aux index et aux métriques, consultez la section « Limites de StructArray ».