本文主要是为了简单整理个人在使用Milvus上的笔记及心得。

基本介绍

Milvus是Zilliz开发的开源向量数据库,专为管理海量向量数据和实现高效相似性搜索(ANN)而设计。其主要使用方式为,创建一个集合,将包括但不限于文字、图片、音频等的非结构化数据通过Embedding模型转变成电脑能读懂的向量值,同时存入元数据以及ID,后续可以实现通过包括但不限于语义相似度搜索、RAG等任务。

向量数据库创建

使用环境

系统版本:MacOS 15.3

Python版本:3.10.16

Milvus版本:pymilvus=2.5.12 + milvus-lite=2.5.1

创建数据库

Milvus数据库形态

Milvus有三种形态的数据库:

Milvus Lite:Milvus的轻量版,目前仅支持Ubuntu >= 20.04和MacOS >= 11.0,均支持x86_64和arm64架构的芯片,截止于当前版本,暂不支持Winodows环境。适用于较小的数据集,多达几百万个向量。

Milvus Standalone:Milvus的单机服务器版本,可以通过Docker进行部署,目前Windows版本可以通过此方式来使用Milvus【安装Docker版Milvus方法】

Milvus Distributed:Milvus的集群版本,具体请参考Milvus官网。

本文仅展示如何使用Milvus,所以采用的是Milvus Lite的形态。Python在使用Milvus时,通过统一的pymilvus SDK进行操作,故以上三种版本在使用体验上基本无太大区别,完全可以实现,使用Lite版进行demo开发,然后快速无缝切换到Standalone或Distributed版本。

连接数据库

连接数据库有两种方式,分别在本地连接数据库和在服务器连接数据库

连接本地版本(仅限于Milvus Lite)

from pymilvus import MilvusCilent

client = MilvusClient(
    "/milvus_demo.db"
)

连接服务器版本(包括Standalone和Distributed版本)

from pymilvus import MilvusCilent

client = MilvusClient(
    uri="http://{ip地址}:{port}",
    token="{帐号}:{密码}"
)

创建Collection

什么是Collection

Collection是Milvus中的一个存储概念,类似于MySQL等SQL数据库中表的概念。而需要创建Collection,则需要先创建Schema,即类似于先创建表字段,再组成一个完整的表。

如何创建Schema

创建Schema从2.4.x版本后,语句得到了简化。其底层则是封装了CollectionSchema 以及FieldSchema 这两种方法。

from pymilvus import MilvusCilent

schema = MilvusClient.create_schema()
MilvusClient.create_schema() 方法的官方注释(通过DeepSeek翻译成了中文)

Help on CollectionSchema in module pymilvus.orm.schema object:

class CollectionSchema(builtins.object)

| CollectionSchema(fields: List, description: str = '', functions: Optional[List] = None, **kwargs)

|

| 此处定义的方法:

|

| eq(self, other: object)

| 模式(schema)中字段的顺序必须保持一致。

|

| init(self, fields: List, description: str = '', functions: Optional[List] = None, **kwargs)

| 初始化 self。请参考 help(type(self)) 获取准确的签名信息。

|

| len(self) -> int

|

| repr(self) -> str

| 返回 repr(self)。

|

| add_field(self, field_name: str, datatype: pymilvus.client.types.DataType, **kwargs)

|

| add_function(self, function: 'Function')

|

| to_dict(self)

|

| verify(self)

|

| ----------------------------------------------------------------------

| 此处定义的类方法:

|

| construct_from_dict(raw: Dict) from builtins.type

|

| ----------------------------------------------------------------------

| 此处定义的只读属性:

|

| description

| 返回 CollectionSchema 的文本描述。

|

| :return str:

| CollectionSchema 的描述文本,操作成功时返回。

|

| :example:

| >>> from pymilvus import FieldSchema, CollectionSchema, DataType

| >>> field = FieldSchema("int64", DataType.INT64, description="int64", is_primary=True)

| >>> schema = CollectionSchema(fields=[field], description="测试获取描述")

| >>> schema.description

| '测试获取描述'

|

| fields

| 返回关于 CollectionSchema 的字段信息。

|

| :return list:

| FieldSchema 的列表,操作成功时返回。

|

| :example:

| >>> from pymilvus import FieldSchema, CollectionSchema, DataType

| >>> field = FieldSchema("int64", DataType.INT64, description="int64", is_primary=True)

| >>> schema = CollectionSchema(fields=[field])

| >>> schema.fields

| [<pymilvus.schema.FieldSchema object at 0x7fd3716ffc50>]

|

| functions

| 返回 CollectionSchema 的函数列表。

|

| :return list:

| Function 的列表,操作成功时返回。

|

| partition_key_field

|

| primary_field

|

| ----------------------------------------------------------------------

| 此处定义的数据描述符:

|

| dict

| 用于实例变量的字典(如果已定义)

|

| weakref

| 指向该对象的弱引用列表(如果已定义)

|

| auto_id

| 主键是否自动生成。

|

| :return bool:

| * True: 如果主键是自动生成的,

| * False: 否则。

|

| :example:

| >>> from pymilvus import FieldSchema, CollectionSchema, DataType

| >>> field = FieldSchema("int64", DataType.INT64, description="int64", is_primary=True)

| >>> schema = CollectionSchema(fields=[field])

| >>> schema.auto_id

| False

|

| enable_dynamic_field

|

| ----------------------------------------------------------------------

| 此处定义的数据及其他属性:

|

| hash = None

如何添加字段

from pymilvus import DataType

# 主字段示例
schema.add_field(field_name="my_id", datatype=DataType.INT64, is_primary=True)
# 向量字段示例
schema.add_field(field_name="my_vector", datatype=DataType.FLOAT_VECTOR, dim=5)
# 标量字段示例
schema.add_field(field_name="my_varchar", datatype=DataType.VARCHAR, max_length=512)

字段类型

Schema的字段类型主要分为三类:主字段(即主键)、向量字段、标量字段,具体各个字段的详细细节还请参考官方文档内容。

主字段

主字段主要设置数据的主键信息

1、主字段只接受INT64VARCHAR 两种类型,主字段默认为INT64

2、通过is_primary 属性设置来判断是否为主字段,默认为False ,设置为True 时则说明为主字段

3、当主字段为INT64 是,可以通过auto_id 属性设置来自动分配主字段值

向量字段

向量字段为存储文本、图片等向量信息等字段

1、向量字段有多种类型的格式可存储:

  • FLOAT_VECTOR 值表示向量字段保存一个32位浮点数列表

  • FLOAT16_VECTOR 值表示向量字段保存一个16位半精度浮点数列表

  • BFLOAT16_VECTOR 值表示向量字段保存一个16位浮点数列表,指数范围与Float32相同

  • INT8_VECTOR 值表示向量字段保存一个8位有符号整数,范围为-128~127

  • BINARY_VECTOR 值表示向量字段保存着一个0和1的列表

  • SPARSE_FLOAT_VECTOR 值表示向量字段可以保存非零数字及其序列号列表,主要表示稀疏向量嵌入

2、通过dim 参数表示向量字段中需要保存的向量嵌入的维度

标量字段

标量字段较为自由,主要存储向量字段所代表的元数据,或存储相应的标签信息

标量字段可以添加以下类型:

  • 字符串类型:VARCHAR ,设置为字符类型时需要额外设置max_length 参数,限制字符串长度

  • 数字类型:INT8INT16INT32INT64FLOATDOUBLE ,实际情况根据实际需要选择使用何种精度的类型

  • 布尔类型:BOOL

  • JSON类型:JSON

  • 数组类型:ARRAY ,当标量字段设置为数组类型时,需要通过element_type对数组的内容也进行类型设置,且需要确保数组内的所有元素的数据类型都相同,并且通过max_capacity 来设置每个数组的最大长度

设置索引参数

索引作用类似于常规关系型数据库中的概念,主要作用是加速对该字段的搜索速度。

# 创建索引
index_params = client.prepare_index_params()
# 添加索引
index_params.add_index(
    field_name="my_id",
    index_type="AUTOINDEX"
)
# 为向量添加索引
index_params.add_index(
    field_name="my_vector", 
    index_type="AUTOINDEX",
    metric_type="COSINE"
)

为向量添加索引时有三种类型,分别是欧氏距离 (L2)、内积 (IP)、余弦相似度 (COSINE)

创建Collection

当Schema以及索引准备好后,就可以创建Collection了

# 创建Collection
client.create_collection(
    collection_name="collection_name",
    schema=schema,
    index_params=index_params
)
# 查看Collection状态
res = client.get_load_state(
    collection_name="collection_name"
)

print(res)

以上就是整个Milvus向量数据库的创建过程了。

样例

下面是完整的一段创建语句

from pymilvus import MilvusClient,DataType

client = MilvusClient("./Milvus_Database/milvus_demo_01.db")

# 定义集合
collection_name = "food_classification"
# 检查集合是否存在,如果存在则删除
if client.has_collection(collection_name):
    client.drop_collection(collection_name)
    print(f"Collection '{collection_name}' 已删除.")

# 创建集合
schema = client.create_schema()
# 主字段示例
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
# 向量字段示例
schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=4096)
# 标量字段示例
schema.add_field(field_name="varchar", datatype=DataType.VARCHAR, max_length=512)

# 创建索引

index_params = client.prepare_index_params()
# 添加索引
index_params.add_index(
    field_name="id",
    index_type=""
)
# 为向量添加索引
index_params.add_index(
    field_name="vector", 
    index_type="AUTOINDEX",
    metric_type="COSINE"
)

# 创建Collection
client.create_collection(
    collection_name="food_classification",
    schema=schema,
    index_params=index_params
)
# 查看Collection状态
res = client.get_load_state(
    collection_name="food_classification"
)

print(res)
# {'state': <LoadState: Loaded>}

index_list = client.list_indexes(
    collection_name="food_classification" # Specify the collection name
)
print(index_list)
# ['id', 'vector']

参考链接

Milvus官方文档:https://milvus.io/docs/