milvus教程:collection和scheme

环境配置:可以看上一节

一.数据库使用

  1. 连接 Milvus Standalone
  2. 创建数据库 my_database_1(无额外属性)
  3. 创建数据库 my_database_2(设置副本数为 3)
  4. 列出所有数据库
  5. 查看默认数据库(default)详情
  6. 修改 my_database_1 属性:限制最大集合数为 10
  7. 删除 my_database_1 的 max.collections 限制
  8. 切换到 my_database_2(后续所有操作都作用于该库)
  9. 删除数据库
from pymilvus import MilvusClient, exceptions

# ——————————————
# 1. 连接 Milvus Standalone
# ——————————————
# uri: 协议+地址+端口,默认为 http://docker_IP:19530
# token: "用户名:密码",默认 root:Milvus
client = MilvusClient(
    uri="http://IP:19531",
    token="root:Milvus"
)

# ——————————————
# 2. 创建数据库 my_database_1(无额外属性)
# ——————————————
try:
    client.create_database(db_name="my_database_1")
    print("✓ my_database_1 创建成功")
except exceptions.MilvusException:
    print("ℹ my_database_1 已存在")

# ——————————————
# 3. 创建数据库 my_database_2(设置副本数为 3)
# ——————————————
client.create_database(
    db_name="my_database_2",
    properties={"database.replica.number": 3}
)
print("✓ my_database_2 创建成功,副本数=3")

# ——————————————
# 4. 列出所有数据库
# ——————————————
db_list = client.list_databases()
print("当前所有数据库:", db_list)

# ——————————————
# 5. 查看默认数据库(default)详情
# ——————————————
default_info = client.describe_database(db_name="default")
print("默认数据库详情:", default_info)

# ——————————————
# 6. 修改 my_database_1 属性:限制最大集合数为 10
# ——————————————
client.alter_database_properties(
    db_name="my_database_1",
    properties={"database.max.collections": 10}
)
print("✓ 已为 my_database_1 限制最大集合数为 10")

# ——————————————
# 7. 删除 my_database_1 的 max.collections 限制
# ——————————————
client.drop_database_properties(
    db_name="my_database_1",
    property_keys=["database.max.collections"]
)
print("✓ 已移除 my_database_1 的最大集合数限制")

# ——————————————
# 8. 切换到 my_database_2(后续所有操作都作用于该库)
# ——————————————
client.use_database(db_name="my_database_2")
print("✓ 已切换当前数据库为 my_database_2")

# ——————————————
# 9. 删除数据库 my_database_2
#    (注意:如果库内有 Collection,需先 client.drop_collection() 将其清空)
# ——————————————
client.drop_database(db_name="my_database_2")
print("✓ my_database_2 已删除")

# ——————————————
# 10. 删除数据库 my_database_1
# ——————————————
client.drop_database(db_name="my_database_1")
print("✓ my_database_1 已删除")
✓ my_database_1 创建成功
✓ my_database_2 创建成功,副本数=3
当前所有数据库: ['my_database_1', 'my_database_2', 'default']
默认数据库详情: {'name': 'default'}
✓ 已为 my_database_1 限制最大集合数为 10
✓ 已移除 my_database_1 的最大集合数限制
✓ 已切换当前数据库为 my_database_2
✓ my_database_2 已删除
✓ my_database_1 已删除

二.Collection

Collection:在 Milvus 中,Collection(集合)是存储向量和其相关元数据的核心对象,可以类比为传统数据库中的“表”。

在这里插入图片描述

2.1.TTL

在 Milvus 中,设置 Collection 的 TTL(Time-To-Live)属性 是为了控制:

插入数据在内存中的生存时间,即:多长时间后这批数据会自动从内存中移除,不再参与检索。

client.create_collection(
    collection_name="example_collection",
    dimension=128,
    ttl_seconds=60
)

这表示:

  • 插入到该集合中的数据,只会在内存中保留 60 秒
  • 超过 60 秒后,这部分数据就会自动被 Milvus 标记过期
  • 这些数据将不再参与 向量检索,也不会占用 检索内存资源

2.2.Milvus 是“冷热分离”的架构

在 Milvus 中,必须先将数据加载到内存(RAM)中,才能进行向量检索

Milvus 为了高性能向量搜索,采用冷热数据分离设计:

数据状态存储位置能否检索说明
未加载磁盘 / 持久化❌ 不可检索仅存储,节省内存资源
已加载内存(RAM)✅ 可检索向量数据加载到内存才能计算相似度

2.3.Partition

Partition 是 Collection 内部的数据子集,用于逻辑分组、分批插入、加速查询。

✅ 为什么需要 Partition?

如果你要处理 大规模数据(百万、千万、甚至上亿条向量),把所有数据放在一个 Collection 中不够灵活:

  • 检索慢(因为全表搜索)
  • 不方便管理(比如不同用户/场景的数据混在一起)

引入 Partition 后,你可以:

  • 按条件划分数据(如按“用户”“时间”“类别”等)
  • 检索时只针对部分 Partition,提高速度
  • 分批管理加载 / 卸载 Partition,节省内存

📦 举个例子

比如你有一个集合 product_vectors,表示商品的向量数据。

你可以按商品类型创建分区:

Partition 名称内容说明
shoes所有鞋类商品向量
phones手机类商品向量
books图书类商品向量

检索时只搜索某个分区:

client.search(
    collection_name="product_vectors",
    partition_names=["phones"],  # 只搜索手机
    ...
)

2.4.Alias

Alias 是指向某个 Collection 的“虚拟名称”,可以随时修改指向的真实集合,不影响客户端代码逻辑。

📌 举个例子:

你有两个 Collection:

  • products_v1:旧版本的商品向量集合
  • products_v2:新版本,已经完成向量更新

此时你可以创建一个别名:

client.create_alias("products", "products_v1")

客户端代码里一直用别名 products

client.search(collection_name="products", ...)

上线新模型后,只需切换别名指向:

client.alter_alias("products", "products_v2")

这样做的好处?客户端代码不用改,就实现了“无感知热切换”。

❗ 注意事项

  • Alias 是 一对一映射:一个别名只能指向一个 Collection
  • 一个 Collection 可以被多个 alias 指向
  • 检索时如果用 alias,必须确保其所指 Collection 已加载(load_collection)
操作作用
create_alias(alias, collection)创建一个别名,初始指向某个 Collection
alter_alias(alias, new_collection)修改别名指向的 Collection,实现热切换
drop_alias(alias)删除别名
list_aliases(collection_name=...)查看某集合的所有别名

2.5.演示代码

from pymilvus import MilvusClient

# ——————————————
# 0. 连接 Milvus
# ——————————————
client = MilvusClient(
    uri="http://IP:19530",
    token="root:Milvus"
)
print("✓ 已连接 Milvus接口")

# ——————————————
# 1. 创建 Collection(快速模式)
# ——————————————
# 检查并删除已存在的集合
collection_name = "quick_setup"
if collection_name in client.list_collections():
    client.drop_collection(collection_name=collection_name)
    print(f"✓ 已删除已存在的集合 {collection_name}")

# 没有定义scheme
# 使用快捷方式创建一个维度为 5 的向量集合(Quick Setup 模式)
client.create_collection(
    collection_name=collection_name,
    dimension=5
)
print(f"✓ {collection_name} 已创建")

# ——————————————
# 2. 列出所有 Collections
# ——————————————
cols = client.list_collections()
print("当前所有集合:", cols)

# ——————————————
# 3. 查看 Collection 详情
# ——————————————
info = client.describe_collection(collection_name=collection_name)
print(f"{collection_name} 详情:", info)

# ——————————————
# 4. 重命名 Collection
# ——————————————
new_collection_name = "quick_renamed"
if new_collection_name in client.list_collections():
    client.drop_collection(collection_name=new_collection_name)
    print(f"✓ 已删除已存在的集合 {new_collection_name}")

client.rename_collection(
    old_name=collection_name,
    new_name=new_collection_name
)
print(f"✓ {collection_name} 已重命名为 {new_collection_name}")

# ——————————————
# 5. 修改 Collection 属性(设置 TTL 60 秒)
# ——————————————
client.alter_collection_properties(
    collection_name=new_collection_name,
    properties={"collection.ttl.seconds": 60}
)
print(f"✓ 已为 {new_collection_name} 设置 TTL=60s")

# ——————————————
# 6. 删除 Collection 属性(TTL)
# ——————————————
client.drop_collection_properties(
    collection_name=new_collection_name,
    property_keys=["collection.ttl.seconds"]
)
print(f"✓ 已删除 {new_collection_name} 的 TTL 属性")

# ——————————————
# 7. 加载集合(将数据加载到内存中)
# ——————————————
client.load_collection(collection_name=new_collection_name)
state = client.get_load_state(collection_name=new_collection_name) # 检查加载状态
print("加载状态:", state)

# ——————————————
# 8. 释放集合(将数据从内存中释放)
# ——————————————
client.release_collection(collection_name=new_collection_name)
state = client.get_load_state(collection_name=new_collection_name) # 检查释放状态
print("释放后状态:", state)

# ——————————————
# 9. 管理 Partition
# ——————————————
# 9.1 列出 Partition(默认只有 "_default")
parts = client.list_partitions(collection_name=new_collection_name)
print("Partition 列表:", parts)

# 9.2 创建新 Partition
client.create_partition(
    collection_name=new_collection_name,
    partition_name="partA"
)
print("✓ 已创建 partition partA")
print("更新后 Partition 列表:", client.list_partitions(new_collection_name))

# 9.3 检查 Partition 是否存在
exists = client.has_partition(
    collection_name=new_collection_name,
    partition_name="partA"
)
print("partA 存在?", exists)

# 9.4 加载 & 释放 指定 Partition 【存入内存】
client.load_partitions(
    collection_name=new_collection_name,
    partition_names=["partA"]
)
print("partA 加载状态:", client.get_load_state(new_collection_name, partition_name="partA"))
# 释放 Partition
client.release_partitions(
    collection_name=new_collection_name,
    partition_names=["partA"]
)
print("partA 释放后状态:", client.get_load_state(new_collection_name, partition_name="partA"))

# 9.5 删除 Partition(需先 release)
client.drop_partition(
    collection_name=new_collection_name,
    partition_name="partA"
)
print("✓ 已删除 partition partA")
print("最终 Partition 列表:", client.list_partitions(new_collection_name))

# ——————————————
# 10. 管理 Alias
# ——————————————
# 10.1 创建 Alias
client.create_alias(collection_name=new_collection_name, alias="alias3")
client.create_alias(collection_name=new_collection_name, alias="alias4")
print("✓ 已创建 alias3, alias4")

# 10.2 列出 Alias
aliases = client.list_aliases(collection_name=new_collection_name)
print("当前 aliases:", aliases)

# 10.3 查看 Alias 详情
desc = client.describe_alias(alias="alias3")
print("alias3 详情:", desc)

# 10.4 重新分配 Alias
client.alter_alias(collection_name=new_collection_name, alias="alias4")
print("✓ 已将 alias4 重新分配给 quick_renamed")

# 10.5 删除 Alias
client.drop_alias(alias="alias3")
print("✓ 已删除 alias3")
print("剩余 aliases:", client.list_aliases(new_collection_name))

# ——————————————
# 11. 删除 Collection
# ——————————————
client.drop_collection(collection_name=new_collection_name)
print(f"✓ 集合 {new_collection_name} 已删除")
✓ 已连接 Milvus接口
✓ quick_setup 已创建
当前所有集合: ['quick_setup']
quick_setup 详情: {'collection_name': 'quick_setup', 'auto_id': False, 'num_shards': 1, 'description': '', 'fields': [{'field_id': 100, 'name': 'id', 'description': '', 'type': <DataType.INT64: 5>, 'params': {}, 'is_primary': True}, {'field_id': 101, 'name': 'vector', 'description': '', 'type': <DataType.FLOAT_VECTOR: 101>, 'params': {'dim': 5}}], 'functions': [], 'aliases': [], 'collection_id': 458770152609592009, 'consistency_level': 2, 'properties': {}, 'num_partitions': 1, 'enable_dynamic_field': True}
✓ quick_setup 已重命名为 quick_renamed
✓ 已为 quick_renamed 设置 TTL=60s
✓ 已删除 quick_renamed 的 TTL 属性
加载状态: {'state': <LoadState: Loaded>}
释放后状态: {'state': <LoadState: NotLoad>}
Partition 列表: ['_default']
✓ 已创建 partition partA
更新后 Partition 列表: ['_default', 'partA']
partA 存在? True
partA 加载状态: {'state': <LoadState: Loaded>}
partA 释放后状态: {'state': <LoadState: NotLoad>}
✓ 已删除 partition partA
最终 Partition 列表: ['_default']
✓ 已创建 alias3, alias4
当前 aliases: {'aliases': ['alias3', 'alias4'], 'collection_name': 'quick_renamed', 'db_name': 'default'}
alias3 详情: {'alias': 'alias3', 'collection_name': 'quick_renamed', 'db_name': 'default'}
✓ 已将 alias4 重新分配给 quick_renamed
✓ 已删除 alias3
剩余 aliases: {'aliases': ['alias4'], 'collection_name': 'quick_renamed', 'db_name': 'default'}
✓ 集合 quick_renamed 已删除

三.Scheme

schema 定义了 Collections 的数据结构。创建 Collections 时,需要根据自己的要求设计模式。

类似于,你将怎么定义表的结构(列名)

from pymilvus import MilvusClient, DataType

# ——————————————
# 0. 连接 Milvus
# ——————————————
client = MilvusClient(
    uri="http://IP:19530",
    token="root:Milvus"
)
print("✓ 已连接 Milvus接口")

# ——————————————
# 1. 创建基本 Schema
# ——————————————
schema = MilvusClient.create_schema()
print("✓ 已创建空 Schema")

# ——————————————
# 2. 添加主键字段(Primary Field)
# ——————————————
# 2.1 INT64类型主键(手动指定ID)
schema.add_field(
    field_name="id",
    datatype=DataType.INT64,
    is_primary=True,  # 设置为主键
    auto_id=False     # 不自动生成ID
)

# 2.2 VARCHAR类型主键(自动生成ID)
# schema.add_field(
#     field_name="doc_id",
#     datatype=DataType.VARCHAR,
#     is_primary=True,  # 设置为主键
#     auto_id=True,     # 自动生成ID
#     max_length=100    # VARCHAR类型需要指定最大长度
# )
print("✓ 已添加主键字段")

# ——————————————
# 3. 添加向量字段(Vector Field)
# ——————————————
# 3.1 Dense Vector (浮点向量)
schema.add_field(
    field_name="text_vector",
    datatype=DataType.FLOAT_VECTOR,  # 32位浮点向量
    dim=768                          # 向量维度
)

# 3.2 Binary Vector (二进制向量)
schema.add_field(
    field_name="image_vector",
    datatype=DataType.BINARY_VECTOR,  # 二进制向量
    dim=256                           # 维度必须是8的倍数
)
print("✓ 已添加向量字段")

# ——————————————
# 4. 添加标量字段(Scalar Field)
# ——————————————
# 4.1 字符串字段
schema.add_field(
    field_name="title",
    datatype=DataType.VARCHAR,
    max_length=200,
    # 可以为空且有默认值
    is_nullable=True,
    default_value="untitled"
)

# 4.2 数值字段
schema.add_field(
    field_name="age",
    datatype=DataType.INT32,
    is_nullable=False  # 不可为空
)

# 4.3 布尔字段
schema.add_field(
    field_name="is_active",
    datatype=DataType.BOOL,
    default_value=True  # 默认值为True
)

# 4.4 JSON字段
schema.add_field(
    field_name="metadata",
    datatype=DataType.JSON
)

# 4.5 数组字段
schema.add_field(
    field_name="tags",
    datatype=DataType.ARRAY,
    element_type=DataType.VARCHAR,  # 数组元素类型
    max_capacity=10,                # 数组最大容量
    max_length=50                   # 每个元素最大长度
)
print("✓ 已添加标量字段")

# ——————————————
# 5. 添加动态字段(Dynamic Field)
# ——————————————
# schema.add_field(
#     field_name="dynamic_field",
#     datatype=DataType.VARCHAR,
#     is_dynamic=True,    # 设置为动态字段
#     max_length=500
# )
print("✓ 已添加动态字段")

# ——————————————
# 6. 使用Schema创建Collection
# ——————————————
collection_name = "document_store10"
client.create_collection(
    collection_name=collection_name,
    schema=schema
)
print(f"✓ 已创建集合 {collection_name}")

# ——————————————
# 7. 修改Collection字段
# ——————————————
# 添加新字段
# client.alter_collection_field(
#     collection_name=collection_name,
#     field_name="tags",
#     field_params={
#         "max_capacity": 64
#     }
# )
# print("✓ 已添加新字段")

# ——————————————
# 8. 查看Collection详情
# ——————————————
info = client.describe_collection(collection_name=collection_name)
print("Collection详情:", info)

# ——————————————
# 9. 清理
# ——————————————
client.drop_collection(collection_name=collection_name)
print("✓ 已删除测试集合")
✓ 已连接 Milvus接口
✓ 已创建空 Schema
✓ 已添加主键字段
✓ 已添加向量字段
✓ 已添加标量字段
✓ 已添加动态字段
✓ 已创建集合 document_store10
Collection详情: {'collection_name': 'document_store10', 'auto_id': False, 'num_shards': 1, 'description': '', 'fields': [{'field_id': 100, 'name': 'id', 'description': '', 'type': <DataType.INT64: 5>, 'params': {}, 'is_primary': True}, {'field_id': 101, 'name': 'text_vector', 'description': '', 'type': <DataType.FLOAT_VECTOR: 101>, 'params': {'dim': 768}}, {'field_id': 102, 'name': 'image_vector', 'description': '', 'type': <DataType.BINARY_VECTOR: 100>, 'params': {'dim': 256}}, {'field_id': 103, 'name': 'title', 'description': '', 'type': <DataType.VARCHAR: 21>, 'params': {'max_length': 200}, 'default_value': string_data: "untitled"
}, {'field_id': 104, 'name': 'age', 'description': '', 'type': <DataType.INT32: 4>, 'params': {}}, {'field_id': 105, 'name': 'is_active', 'description': '', 'type': <DataType.BOOL: 1>, 'params': {}, 'default_value': bool_data: true
}, {'field_id': 106, 'name': 'metadata', 'description': '', 'type': <DataType.JSON: 23>, 'params': {}}, {'field_id': 107, 'name': 'tags', 'description': '', 'type': <DataType.ARRAY: 22>, 'params': {'max_length': 50, 'max_capacity': 10}, 'element_type': <DataType.VARCHAR: 21>}], 'functions': [], 'aliases': [], 'collection_id': 458770152609609581, 'consistency_level': 2, 'properties': {}, 'num_partitions': 1, 'enable_dynamic_field': False}
✓ 已删除测试集合

四.实体:Entity

在 Milvus 中,Entity(实体) 是指 插入到 Collection(集合)中的一条数据记录

✅ 举个例子

你要插入一张商品图像的向量表示到 Milvus:

entities = [
    {"product_id": 1, "image_vector": [0.1, 0.2, 0.3, 0.4], "category": "shoe"},
    {"product_id": 2, "image_vector": [0.9, 0.8, 0.7, 0.6], "category": "book"},
]

client.insert(
    collection_name="products",
    data=entities
)

五.实体:Upsert

当你需要更新集合中的实体,或者不确定是更新还是插入时,可以尝试使用 Upsert 操作。

务必确保 Upsert 请求中包含的实体包含主键,否则会报错。

  1. 检查Collection的主字段是否启用了AutoId。
    • 如果是,Milvus 会将实体中的主键替换为自动生成的主键,并插入数据。
    • 如果没有,Milvus 将使用实体携带的主键来插入数据。
  2. 根据Upsert请求中包含的Entity的主键值执行删除操作。
    在这里插入图片描述
from pymilvus import MilvusClient
import random

# 连接到 Milvus
client = MilvusClient(
    uri="http://1.14.201.121:19530",
    token="root:Milvus"
)

# 1. 创建集合
# 检查集合是否存在,如果存在则删除
if client.has_collection("quick_setup"):
    client.drop_collection("quick_setup")

# 创建集合
client.create_collection(
    collection_name="quick_setup",
    dimension=5,  # vector 维度
    primary_field_name="id",
    vector_field_name="vector",
    id_type="int"
)

print("集合创建成功")

# 2. 插入实体(Entity)
data=[
    {"id": 0, "vector": [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592], "color": "pink_8682"},
    {"id": 1, "vector": [0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104], "color": "red_7025"},
    {"id": 2, "vector": [0.43742130801983836, -0.5597502546264526, 0.6457887650909682, 0.7894058910881185, 0.20785793220625592], "color": "orange_6781"},
    {"id": 3, "vector": [0.3172005263489739, 0.9719044792798428, -0.36981146090600725, -0.4860894583077995, 0.95791889146345], "color": "pink_9298"},
    {"id": 4, "vector": [0.4452349528804562, -0.8757026943054742, 0.8220779437047674, 0.46406290649483184, 0.30337481143159106], "color": "red_4794"},
    {"id": 5, "vector": [0.985825131989184, -0.8144651566660419, 0.6299267002202009, 0.1206906911183383, -0.1446277761879955], "color": "yellow_4222"},
    {"id": 6, "vector": [0.8371977790571115, -0.015764369584852833, -0.31062937026679327, -0.562666951622192, -0.8984947637863987], "color": "red_9392"},
    {"id": 7, "vector": [-0.33445148015177995, -0.2567135004164067, 0.8987539745369246, 0.9402995886420709, 0.5378064918413052], "color": "grey_8510"},
    {"id": 8, "vector": [0.39524717779832685, 0.4000257286739164, -0.5890507376891594, -0.8650502298996872, -0.6140360785406336], "color": "white_9381"},
    {"id": 9, "vector": [0.5718280481994695, 0.24070317428066512, -0.3737913482606834, -0.06726932177492717, -0.6980531615588608], "color": "purple_4976"}
]

res = client.insert(
    collection_name="quick_setup",
    data=data
)

print(res)

# 3. 更新实体
update_data = [
    {"id": 0, "vector": [random.random() for _ in range(5)], "color": "updated_pink_8682"},
    {"id": 1, "vector": [random.random() for _ in range(5)], "color": "updated_red_7025"}
]

res = client.upsert(
    collection_name="quick_setup",
    data=update_data
)
print("\n更新结果:", res)

# 4. 删除实体
res = client.delete(
    collection_name="quick_setup",
    ids=[0]
)
print("\n删除结果:", res)

# 5. 查询实体
res = client.query(
    collection_name="quick_setup",
    filter="id in [1,2]",
    output_fields=["id", "color"]
)
print("\n查询结果:", res)
{'insert_count': 10, 'ids': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
更新结果: {'upsert_count': 2}
删除结果: {'delete_count': 1}
查询结果: data: ["{'id': 1, 'color': 'updated_red_7025'}", "{'id': 2, 'color': 'orange_6781'}"]

六.Function

您可以在 Milvus 创建集合时设置函数来导出字段。例如,全文搜索功能使用用户自定义函数从特定的 varchar 字段导出稀疏向量字段。

七.Consistency Level(数据一致性)

分布式数据库系统通常使用一致性级别来定义跨数据节点和副本的数据相同性。

可以在创建集合或在集合内进行相似性搜索时设置单独的一致性级别。适用的一致性级别包括:Strong, Bounded Staleness, Session, Eventually

在这里插入图片描述

client.create_collection(
	collection_name="my_collection",
	schema=schema,
	consistency_level="Bounded", # Defaults to Bounded if not specified
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值