Skip to main content
Version: User Guides (Cloud)

Alter Collection Schema

As a collection moves from development to production, the fields around each entity often change. You might add scalar fields such as source_uri or review_status for filtering and application logic, add a new vector field for embeddings generated by your application. Alter Collection Schema lets you make supported field changes in place instead of recreating the collection.

📘Notes

This guide covers field-level schema changes in existing collections. For field property changes, such as changing max_length on a VARCHAR field or max_capacity on an ARRAY field, refer to Alter Collection Field. For dynamic field behavior, refer to Dynamic Field and Modify Collection.

Limits

  • Added user-defined fields must be nullable. Set nullable=True when calling add_collection_field(). For existing entities, the added field is NULL unless you add a scalar field with a default_value.

  • Adding user-defined scalar fields is supported in Milvus 2.6.x and later. Adding user-defined vector fields is supported in Milvus 2.6.18 and later.

  • Field names must be unique among fields in the collection.

📘Notes

For schema changes outside supported add and drop operations, recreate or migrate the collection.

Add fields to an existing collection

Choose the add-field path based on how the field values are produced:

In these cases, the total number of fields cannot exceed the Zilliz Cloud field-count limit. For details, refer to Zilliz Cloud Limits.

Add user-defined scalar fields

Use add_collection_field() to add a user-defined scalar field to an existing collection.

This differs from storing arbitrary keys in the dynamic field: after the schema update is available, the new scalar field becomes a regular part of the collection schema. You can insert or upsert values into it, create indexes on it where supported, use it in queries and search filters, and return it in query or search output.

Because existing entities were inserted before the new field existed, every added user-defined scalar field must be nullable:

  • If you add a scalar field with nullable=True and no default_value, existing entities return NULL for the new field.

  • If you add a scalar field with nullable=True and default_value, existing entities return the default value instead of NULL.

Scalar filter expressions do not match NULL scalar values. For details, refer to Nullable Fields.

Example: Add a nullable scalar field

The following example adds a nullable source field to an existing collection named product_catalog.

from pymilvus import DataType, MilvusClient

client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")

client.add_collection_field(
collection_name="product_catalog",
field_name="source",
data_type=DataType.VARCHAR,
max_length=128,
nullable=True,
)

After the field is added, entities that already existed in the collection return NULL for source. New entities can set source during insert or upsert.

Example: Add a scalar field with a default value

If existing entities should return a concrete value instead of NULL, specify default_value when adding the field. The following example adds a review_status field and uses "unreviewed" as the default value.

from pymilvus import DataType, MilvusClient

client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")

client.add_collection_field(
collection_name="product_catalog",
field_name="review_status",
data_type=DataType.VARCHAR,
max_length=32,
nullable=True,
default_value="unreviewed",
)

After the field is added, entities that already existed in the collection return "unreviewed" for review_status. New entities can set a different value or use the default value when no value is provided.

Add user-defined vector fields

Use add_collection_field() to add a user-defined vector field when your application generates embeddings and writes vector values to Zilliz Cloud.

Every added user-defined vector field must be nullable. Existing entities have NULL for the new vector field until you write vector values through upsert or a backfill workflow. New entities can include the vector field during insert. Vector search skips entities whose vector value is NULL. For details, refer to Nullable Fields.

Example: Add a nullable vector field

The following example adds a nullable dense vector field named embedding_v2 to an existing collection. Set dim to the dimensionality of the embeddings generated by your application.

from pymilvus import DataType, MilvusClient

client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")

client.add_collection_field(
collection_name="product_catalog",
field_name="embedding_v2",
data_type=DataType.FLOAT_VECTOR,
dim=768,
nullable=True,
)

After the field is added, create an index on the new vector field before searching it:

index_params = client.prepare_index_params()

index_params.add_index(
field_name="embedding_v2",
index_type="AUTOINDEX",
metric_type="COSINE",
)

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

Existing entities have NULL for embedding_v2 and are skipped when you search on this field. To make existing entities searchable through embedding_v2, write non-NULL vector values through upsert workflows. New entities can include embedding_v2 during insert.

FAQ

Why must added user-defined fields be nullable?

Existing entities were inserted before the new field existed, so they do not have values for that field. Setting nullable=True lets Zilliz Cloud represent the missing value as NULL until your application writes a value or, for scalar fields, until a default value applies.

This rule applies to user-defined scalar fields and user-defined vector fields added with add_collection_field(). It does not apply to vector fields generated by functions, which cannot be nullable.

What happens to existing entities after I add a user-defined field?

For a user-defined scalar field, existing entities return NULL unless you set a default_value. If you set a default_value, existing entities return that default value.

For a user-defined vector field, existing entities have NULL for the new vector field. Vector search on the added field skips entities whose vector value is NULL. To make existing entities searchable through the new vector field, write non-NULL vector values through upsert or a backfill workflow. New entities can include the new vector field during insert.

Do I need to wait after altering a collection schema?

Usually, no manual wait is required. If your next operation depends on the updated schema, you can call describe_collection() first to confirm the schema that Zilliz Cloud currently returns.

In a distributed deployment, there can be a short propagation window while Zilliz Cloud components refresh collection metadata. If an operation immediately after the schema change fails with a schema-related error, refresh the schema and retry the operation.

What happens if I add a scalar field with the same name as a dynamic field key?

If dynamic field is enabled, you can add a scalar field with the same name as an existing dynamic field key. The new scalar field masks the dynamic field key in normal query output, but the original dynamic data is preserved in $meta.

For example, if existing entities store a dynamic key named source, and you later add a scalar field named source, normal output for source refers to the scalar field. To access the original dynamic value, use the metapathsyntax,suchasmeta path syntax, such as `meta["source"]`.