本节介绍如何通过客户端向 Milvus 中插入数据。您还可以使用 MilvusDM 将数据迁移到 Milvus,MilvusDM 是一款专门用于使用 Milvus 导入和导出数据的开源工具。
Milvus 2.1 支持标量字段上的 VARCHAR 数据类型。为VARCHAR类型标量字段构建索引时,默认索引类型为字典树。
以下示例插入 2,000 行随机生成的数据作为示例数据(Milvus CLI 示例使用包含类似数据的预构建远程 CSV 文件)。实际应用程序可能会使用比示例更高维的向量。您可以准备自己的数据来替换示例。
一、新增数据
官方文档:https://milvus.io/docs/insert_data.md
首先,准备要插入的数据。要插入的数据的数据类型必须与集合的模式匹配,否则 Milvus 将引发异常。
Milvus 支持标量字段的默认值,不包括主键字段。这表明在数据插入或更新插入期间某些字段可以留空。
有关更多信息,请参阅创建集合(https://milvus.io/docs/create_collection.md)。
启用动态架构后,您可以在数据中附加动态字段。有关详细信息,请参阅Dynamic Schema。
示例:
import random
from pymilvus import Collection
# 数据构造
data = [
[i for i in range(2000)],
[str(i) for i in range(2000)],
[i for i in range(10000, 12000)],
[[random.random() for _ in range(2)] for _ in range(2000)],
# use `default_value` for a field
[],
# or
None,
# or just omit the field
]
data.append([str("dy"*i) for i in range(2000)])
# 插入数据
# 通过指定partition_name,您可以选择决定将数据插入到哪个分区
collection = Collection("book") # Get an existing collection.
mr = collection.insert(data)
注意:
将实体插入到之前已建立索引的集合中后,无需重新索引该集合,因为 Milvus 会自动为新插入的数据创建索引。
如果之前已经通过 create_index() 为集合建立了索引,Milvus 会自动为后续插入的向量建立索引。然而,直到新插入的向量填满整个段并且新创建的索引文件与前一个索引文件分开时,Milvus 才会构建索引。
当数据插入 Milvus 时,它是分段存储的。段必须达到一定的大小才能被密封和索引。未密封的段将被强力搜索。如果插入后需要立即查找数据,可以在插入数据后调用flush()方法。此方法密封所有剩余的段并将其发送以进行索引。仅在插入会话结束时调用此方法非常重要。过于频繁地调用它会导致数据碎片化,需要稍后进行清理。
Milvus 会自动触发flush()操作。在大多数情况下,不需要手动调用此操作。
插入数据维度限制32,768。
二、更新数据
官方文档:https://milvus.io/docs/upsert_entities.md
本主题介绍如何在 Milvus 中更新插入实体。更新插入是插入和删除操作的组合。
在 Milvus 矢量数据库的上下文中,upsert 是一种数据级操作,如果集合中已存在指定字段,则该操作将覆盖现有实体;如果指定值尚不存在,则插入新实体。以下示例更新插入 3,000 行随机生成的数据作为示例数据。
执行更新插入操作时,请务必注意该操作可能会影响性能。这是因为该操作在执行过程中涉及到删除数据。
示例:
import random
# 准备数据
nb = 3000
dim = 8
vectors = [[random.random() for _ in range(dim)] for _ in range(nb)]
data = [
[i for i in range(nb)],
[str(i) for i in range(nb)],
[i for i in range(10000, 10000+nb)],
vectors,
[str("dy"*i) for i in range(nb)]
]
# 更新数据
from pymilvus import Collection
collection = Collection("book") # Get an existing collection.
mr = collection.upsert(data) #
注意:将实体更新插入到之前已建立索引的集合中后,您无需重新索引该集合,因为 Milvus 会自动为新更新插入的数据创建索引。详细信息,请参阅插入向量后能否创建索引?
当数据更新插入 Milvus 时,它会被更新并插入到段中。段必须达到一定的大小才能被密封和索引。未密封的段将被强力搜索。为了避免任何剩余数据出现这种情况,最好调用flush()。 lush() 调用将密封所有剩余的段并将其发送以进行索引。仅在 upsert 会话结束时调用此方法非常重要。过于频繁地调用它会导致数据碎片化,需要稍后清理。
upsert() 不支持更新主键字段。
upsert() 不适用,如果主键字段的 autoID 设置为 True,则可能会发生错误。
三、删除数据
官方文档:https://milvus.io/docs/delete_data.md
本节介绍如何在 Milvus 中删除实体。
Milvus 支持通过主键或复杂布尔表达式删除实体。通过主键删除实体比通过复杂的布尔表达式删除实体更快、更轻松。这是因为 Milvus 在通过复杂的布尔表达式删除数据时会先执行查询。
- 如果一致性级别设置为低于“强”,则删除后的实体仍然可以立即检索。
- 超出预先指定的时间范围而删除的实体将无法再次检索。
- 频繁的删除操作会影响系统性能。
- 在通过 comlpex 布尔表达式删除实体之前,请确保集合已加载。
- 通过复杂的布尔表达式删除实体不是原子操作。因此,如果中途失败,仍然可能会删除一些数据。
- 仅当一致性设置为Bounded时,才支持通过复杂布尔表达式删除实体。有关详细信息,请参阅一致性(https://milvus.io/docs/consistency.md)。
示例代码:
# 删除条件表达式
expr = "word_count >= 11000"
# expr = "book_name != Unknown"
# expr = "book_id > 5 && word_count <= 9999"
# 调用delete删除
from pymilvus import Collection
collection = Collection("book") # Get an existing collection.
collection.delete(expr)