Champ primaire et AutoID
Chaque collection dans Milvus doit avoir un champ primaire pour identifier de manière unique chaque entité. Ce champ garantit que chaque entité peut être insérée, mise à jour, interrogée ou supprimée sans ambiguïté.
En fonction de votre cas d'utilisation, vous pouvez laisser Milvus générer automatiquement des ID (AutoID) ou attribuer vos propres ID manuellement.
Qu'est-ce qu'un champ primaire ?
Un champ primaire sert de clé unique pour chaque entité d'une collection, comme une clé primaire dans une base de données traditionnelle. Milvus utilise le champ primaire pour gérer les entités pendant les opérations d'insertion, d'upsert, de suppression et de requête.
Exigences clés :
Chaque collection doit avoir exactement un champ primaire.
Les valeurs des champs primaires ne peuvent pas être nulles.
Le type de données doit être spécifié lors de la création et ne peut être modifié ultérieurement.
Types de données pris en charge
Le champ primaire doit utiliser un type de données scalaire pris en charge qui permet d'identifier les entités de manière unique.
Type de données |
Description du type de données |
|---|---|
|
Type entier 64 bits, couramment utilisé avec AutoID. Il s'agit de l'option recommandée pour la plupart des cas d'utilisation. |
|
Type de chaîne de longueur variable. À utiliser lorsque les identifiants d'entité proviennent de systèmes externes (par exemple, codes de produit ou identifiants d'utilisateur). Nécessite la propriété |
Choix entre AutoID et ID manuels
Milvus prend en charge deux modes d'affectation des valeurs de clé primaire.
Mode |
Description |
Recommandé pour |
|---|---|---|
AutoID |
Milvus génère automatiquement des identifiants uniques pour les entités insérées ou importées. |
La plupart des scénarios dans lesquels il n'est pas nécessaire de gérer les identifiants manuellement. |
ID manuel |
Vous fournissez vous-même des identifiants uniques lors de l'insertion ou de l'importation de données. |
Lorsque les identifiants doivent s'aligner sur des systèmes externes ou des ensembles de données préexistants. |
Si vous ne savez pas quel mode choisir, commencez par AutoID pour une ingestion plus simple et une unicité garantie.
Il est conseillé d'utiliser
autoIddans tous les cas, à moins que la définition manuelle des clés primaires ne soit bénéfique.
Démarrage rapide : Utiliser AutoID
Vous pouvez laisser Milvus gérer la génération d'ID automatiquement.
Etape 1 : Créer une collection avec AutoID
Activer auto_id=True dans la définition de votre champ primaire. Milvus se chargera automatiquement de la génération d'identifiants.
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="http://localhost:19530")
schema = client.create_schema()
# Define primary field with AutoID enabled
schema.add_field(
field_name="id", # Primary field name
is_primary=True,
auto_id=True, # Milvus generates IDs automatically; Defaults to False
datatype=DataType.INT64
)
# Define the other fields
schema.add_field(field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=4) # Vector field
schema.add_field(field_name="category", datatype=DataType.VARCHAR, max_length=1000) # Scalar field of the VARCHAR type
# Create the collection
if client.has_collection("demo_autoid"):
client.drop_collection("demo_autoid")
client.create_collection(collection_name="demo_autoid", schema=schema)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
import io.milvus.v2.service.collection.request.DropCollectionReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.build());
CreateCollectionReq.CollectionSchema collectionSchema = CreateCollectionReq.CollectionSchema.builder()
.build();
collectionSchema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.autoID(true)
.build());
collectionSchema.addField(AddFieldReq.builder()
.fieldName("embedding")
.dataType(DataType.FloatVector)
.dimension(4)
.build());
collectionSchema.addField(AddFieldReq.builder()
.fieldName("category")
.dataType(DataType.VarChar)
.maxLength(1000)
.build());
client.dropCollection(DropCollectionReq.builder()
.collectionName("demo_autoid")
.build());
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
.collectionName("demo_autoid")
.collectionSchema(collectionSchema)
.build();
client.createCollection(requestCreate);
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const client = new MilvusClient({
address: "localhost:19530",
});
// Define schema fields
const schema = [
{
name: "id",
description: "Primary field",
data_type: DataType.Int64,
is_primary_key: true,
autoID: true, // Milvus generates IDs automatically
},
{
name: "embedding",
description: "Vector field",
data_type: DataType.FloatVector,
dim: 4,
},
{
name: "category",
description: "Scalar field",
data_type: DataType.VarChar,
max_length: 1000,
},
];
// Create the collection
await client.createCollection({
collection_name: "demo_autoid",
fields: schema,
});
// go
# restful
export SCHEMA='{
"autoID": true,
"fields": [
{
"fieldName": "id",
"dataType": "Int64",
"isPrimary": true,
"elementTypeParams": {}
},
{
"fieldName": "embedding",
"dataType": "FloatVector",
"isPrimary": false,
"elementTypeParams": {
"dim": "4"
}
},
{
"fieldName": "category",
"dataType": "VarChar",
"isPrimary": false,
"elementTypeParams": {
"max_length": "1000"
}
}
]
}'
curl -X POST 'http://localhost:19530/v2/vectordb/collections/create' \
-H 'Content-Type: application/json' \
-d "{
\"collectionName\": \"demo_autoid\",
\"schema\": $SCHEMA
}"
Étape 2 : Insérer des données
Important : N'incluez pas la colonne du champ primaire dans vos données. Milvus génère les identifiants automatiquement.
data = [
{"embedding": [0.1, 0.2, 0.3, 0.4], "category": "book"},
{"embedding": [0.2, 0.3, 0.4, 0.5], "category": "toy"},
]
res = client.insert(collection_name="demo_autoid", data=data)
print("Generated IDs:", res.get("ids"))
# Output example:
# Generated IDs: [461526052788333649, 461526052788333650]
import com.google.gson.*;
import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.response.InsertResp;
List<JsonObject> rows = new ArrayList<>();
Gson gson = new Gson();
JsonObject row1 = new JsonObject();
row1.add("embedding", gson.toJsonTree(new float[]{0.1f, 0.2f, 0.3f, 0.4f}));
row1.addProperty("category", "book");
rows.add(row1);
JsonObject row2 = new JsonObject();
row2.add("embedding", gson.toJsonTree(new float[]{0.2f, 0.3f, 0.4f, 0.5f}));
row2.addProperty("category", "toy");
rows.add(row2);
InsertResp insertR = client.insert(InsertReq.builder()
.collectionName("demo_autoid")
.data(rows)
.build());
System.out.printf("Generated IDs: %s\n", insertR.getPrimaryKeys());
const data = [
{"embedding": [0.1, 0.2, 0.3, 0.4], "category": "book"},
{"embedding": [0.2, 0.3, 0.4, 0.5], "category": "toy"},
];
const res = await client.insert({
collection_name: "demo_autoid",
fields_data: data,
});
console.log(res);
// go
# restful
export INSERT_DATA='[
{
"embedding": [0.1, 0.2, 0.3, 0.4],
"category": "book"
},
{
"embedding": [0.2, 0.3, 0.4, 0.5],
"category": "toy"
}
]'
curl -X POST 'http://localhost:19530/v2/vectordb/entities/insert' \
-H 'Content-Type: application/json' \
-d "{
\"collectionName\": \"demo_autoid\",
\"data\": $INSERT_DATA
}"
Utilisez upsert() au lieu de insert() lorsque vous travaillez avec des entités existantes afin d'éviter les erreurs de duplication d'ID.
Utiliser des ID manuels
Si vous avez besoin de contrôler les identifiants manuellement, désactivez AutoID et fournissez vos propres valeurs.
Étape 1 : Créer une collection sans AutoID
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="http://localhost:19530")
schema = client.create_schema()
# Define the primary field without AutoID
schema.add_field(
field_name="product_id",
is_primary=True,
auto_id=False, # You'll provide IDs manually at data ingestion
datatype=DataType.VARCHAR,
max_length=100 # Required when datatype is VARCHAR
)
# Define the other fields
schema.add_field(field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=4) # Vector field
schema.add_field(field_name="category", datatype=DataType.VARCHAR, max_length=1000) # Scalar field of the VARCHAR type
# Create the collection
if client.has_collection("demo_manual_ids"):
client.drop_collection("demo_manual_ids")
client.create_collection(collection_name="demo_manual_ids", schema=schema)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
import io.milvus.v2.service.collection.request.DropCollectionReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.build());
CreateCollectionReq.CollectionSchema collectionSchema = CreateCollectionReq.CollectionSchema.builder()
.build();
collectionSchema.addField(AddFieldReq.builder()
.fieldName("product_id")
.dataType(DataType.VarChar)
.isPrimaryKey(true)
.autoID(false)
.maxLength(100)
.build());
collectionSchema.addField(AddFieldReq.builder()
.fieldName("embedding")
.dataType(DataType.FloatVector)
.dimension(4)
.build());
collectionSchema.addField(AddFieldReq.builder()
.fieldName("category")
.dataType(DataType.VarChar)
.maxLength(1000)
.build());
client.dropCollection(DropCollectionReq.builder()
.collectionName("demo_manual_ids")
.build());
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
.collectionName("demo_manual_ids")
.collectionSchema(collectionSchema)
.build();
client.createCollection(requestCreate);
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const client = new MilvusClient({
address: "localhost:19530",
username: "username",
password: "Aa12345!!",
});
const schema = [
{
name: "product_id",
data_type: DataType.VARCHAR,
is_primary_key: true,
autoID: false,
},
{
name: "embedding",
data_type: DataType.FLOAT_VECTOR,
dim: 4,
},
{
name: "category",
data_type: DataType.VARCHAR,
max_length: 1000,
},
];
const res = await client.createCollection({
collection_name: "demo_autoid",
schema: schema,
});
// go
# restful
export SCHEMA='{
"autoID": false,
"fields": [
{
"fieldName": "product_id",
"dataType": "VarChar",
"isPrimary": true,
"elementTypeParams": {
"max_length": "100"
}
},
{
"fieldName": "embedding",
"dataType": "FloatVector",
"isPrimary": false,
"elementTypeParams": {
"dim": "4"
}
},
{
"fieldName": "category",
"dataType": "VarChar",
"isPrimary": false,
"elementTypeParams": {
"max_length": "1000"
}
}
]
}'
curl -X POST 'http://localhost:19530/v2/vectordb/collections/create' \
-H 'Content-Type: application/json' \
-d "{
\"collectionName\": \"demo_manual_ids\",
\"schema\": $SCHEMA
}"
Étape 2 : Insérer des données avec vos identifiants
Vous devez inclure la colonne du champ primaire dans chaque opération d'insertion.
# Each entity must contain the primary field `product_id`
data = [
{"product_id": "PROD-001", "embedding": [0.1, 0.2, 0.3, 0.4], "category": "book"},
{"product_id": "PROD-002", "embedding": [0.2, 0.3, 0.4, 0.5], "category": "toy"},
]
res = client.insert(collection_name="demo_manual_ids", data=data)
print("Generated IDs:", res.get("ids"))
# Output example:
# Generated IDs: ['PROD-001', 'PROD-002']
import com.google.gson.*;
import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.response.InsertResp;
List<JsonObject> rows = new ArrayList<>();
Gson gson = new Gson();
JsonObject row1 = new JsonObject();
row1.addProperty("product_id", "PROD-001");
row1.add("embedding", gson.toJsonTree(new float[]{0.1f, 0.2f, 0.3f, 0.4f}));
row1.addProperty("category", "book");
rows.add(row1);
JsonObject row2 = new JsonObject();
row2.addProperty("product_id", "PROD-002");
row2.add("embedding", gson.toJsonTree(new float[]{0.2f, 0.3f, 0.4f, 0.5f}));
row2.addProperty("category", "toy");
rows.add(row2);
InsertResp insertR = client.insert(InsertReq.builder()
.collectionName("demo_manual_ids")
.data(rows)
.build());
System.out.printf("Generated IDs: %s\n", insertR.getPrimaryKeys());
const data = [
{"product_id": "PROD-001", "embedding": [0.1, 0.2, 0.3, 0.4], "category": "book"},
{"product_id": "PROD-002", "embedding": [0.2, 0.3, 0.4, 0.5], "category": "toy"},
];
const insert = await client.insert({
collection_name: "demo_autoid",
fields_data: data,
});
console.log(insert);
// go
# restful
export INSERT_DATA='[
{
"product_id": "PROD-001",
"embedding": [0.1, 0.2, 0.3, 0.4],
"category": "book"
},
{
"product_id": "PROD-002",
"embedding": [0.2, 0.3, 0.4, 0.5],
"category": "toy"
}
]'
# 插入数据
curl -X POST 'http://localhost:19530/v2/vectordb/entities/insert' \
-H 'Content-Type: application/json' \
-d "{
\"collectionName\": \"demo_manual_ids\",
\"data\": $INSERT_DATA
}"
Vos responsabilités :
Veiller à ce que tous les identifiants soient uniques pour toutes les entités
Inclure le champ primaire dans chaque opération d'insertion/importation
Gérer vous-même les conflits d'identifiants et la détection des doublons
Utilisation avancée
Migrer des données avec des AutoID existants
Pour préserver les ID existants lors de la migration des données, activez la propriété allow_insert_auto_id en effectuant l'appel alter_collection_properties. Lorsque cette propriété est définie sur true, Milvus accepte les ID fournis par l'utilisateur même si l'AutoID est activé.
Pour plus de détails sur la configuration, voir Modifier la collecte.
Garantir l'unicité globale de l'AutoID dans les clusters
Lors de l'exécution de plusieurs clusters Milvus, configurer un ID de cluster unique pour chacun afin de s'assurer que les AutoID ne se chevauchent jamais.
Configuration : Modifiez la configuration common.clusterID dans milvus.yaml avant d'initialiser votre cluster :
common:
clusterID: 3 # Must be unique across all clusters (Range: 0-7)
Dans cette configuration, clusterID spécifie l'identifiant unique utilisé dans la génération de l'AutoID, allant de 0 à 7 (prend en charge jusqu'à huit clusters).
Milvus gère l'inversion des bits en interne pour permettre une expansion future sans chevauchement d'ID. Aucune configuration manuelle n'est nécessaire en dehors de la définition de l'ID du cluster.
Référence : Fonctionnement de l'AutoID
Comprendre comment AutoID génère des identifiants uniques en interne peut vous aider à configurer correctement les ID de clusters et à résoudre les problèmes liés aux ID.
AutoID utilise un format structuré de 64 bits pour garantir l'unicité :
[sign_bit][cluster_id][physical_ts][logical_ts]
Segment |
Description de l'identifiant |
|---|---|
|
Réservé à l'usage interne |
|
Identifie le cluster qui a généré l'ID (plage de valeurs : 0-7) |
|
Horodatage en millisecondes de la génération de l'ID |
|
Compteur permettant de distinguer les ID créés dans la même milliseconde |
Même lorsque AutoID est activé avec VARCHAR comme type de données, Milvus génère toujours des ID numériques. Ceux-ci sont stockés sous forme de chaînes numériques d'une longueur maximale de 20 caractères (plage uint64).