跳到主要内容
版本:v2.4.x

启用动态字段

本页介绍如何在 Collection 中使用动态字段,以便灵活插入和检索数据。

概述

Milvus 允许您通过设置每个特定字段的名称和数据类型来定义 Collection 的 Schema,以便在这些字段中创建索引,提高搜索性能。

一旦定义了字段,您就需要在插入数据时包含该字段。如果某些字段并不总是出现在所有数据条目中,该怎么办?这就是动态字段的用武之地。

Collection 中的动态字段是一个名为 $meta 的保留 JSON 字段。它可以以键值对的形式保存非 Schema 定义的字段及其值。使用动态字段,您既可以搜索和查询 Schema 定义的字段,也可以搜索和查询它们可能具有的任何非 Schema 定义的字段。

启用动态字段

在为 Collection 定义模式时,可将enable_dynamic_field 设置为True ,以启用预留动态字段,表示以后插入的任何非模式定义字段及其值都将作为键值对保存在预留动态字段中。

下面的代码段创建了一个带有两个 Schema 定义字段(即 id 和向量)的 Collection,并启用了动态字段。

有关参数的更多信息,请参阅 create_collection()有关参数的更多信息,请参阅 SDK 参考资料中的

有关参数的更多信息,请参阅 createCollection()有关参数的更多信息,请参阅 SDK 参考资料中的

有关参数的更多信息,请参阅 createCollection()有关参数的更多信息,请参阅 SDK 参考资料中的

import random, time
from pymilvus import connections, MilvusClient, DataType

SERVER_ADDR = "http://localhost:19530"

# 1. Set up a Milvus client
client = MilvusClient(
uri=SERVER_ADDR
)

# 2. Create a collection
schema = MilvusClient.create_schema(
auto_id=False,
enable_dynamic_field=True,
)

schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=5)

index_params = MilvusClient.prepare_index_params()

index_params.add_index(
field_name="id",
index_type="STL_SORT"
)

index_params.add_index(
field_name="vector",
index_type="IVF_FLAT",
metric_type="L2",
params={"nlist": 1024}
)

client.create_collection(
collection_name="test_collection",
schema=schema,
index_params=index_params
)

res = client.get_load_state(
collection_name="test_collection"
)

print(res)

# Output
#
# {
# "state": "<LoadState: Loaded>"
# }

插入动态数据

一旦创建了 Collection,就可以开始插入数据,包括将动态数据插入 Collection。

准备数据

在本节中,您需要准备一些随机生成的数据,以便稍后插入。

colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"]
data = []

for i in range(1000):
current_color = random.choice(colors)
current_tag = random.randint(1000, 9999)
data.append({
"id": i,
"vector": [ random.uniform(-1, 1) for _ in range(5) ],
"color": current_color,
"tag": current_tag,
"color_tag": f"{current_color}_{str(current_tag)}"
})

print(data[0])

您可以通过查看第一个条目来查看生成数据的结构。

{
id: 0,
vector: [
0.1275656405044483,
0.47417858592773277,
0.13858264437643286,
0.2390904907020377,
0.8447862593689635
],
color: 'blue',
tag: 2064,
color_tag: 'blue_2064'
}

插入数据

然后,您就可以安全地将数据插入 Collection 中了。

有关参数的更多信息,请参阅 insert()中的

有关参数的更多信息,请参阅 insert()有关参数的更多信息,请参阅 SDK 参考资料中的

有关参数的更多信息,请参阅 insert()有关参数的更多信息,请参阅 SDK 参考资料中的

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

print(res)

# Output
#
# {
# "insert_count": 1000,
# "ids": [
# 0,
# 1,
# 2,
# 3,
# 4,
# 5,
# 6,
# 7,
# 8,
# 9,
# "(990 more items hidden)"
# ]
# }

time.sleep(5)

使用动态字段搜索

如果创建的 Collection 启用了动态字段并插入了非 Schema 定义的字段,则可以在搜索或查询的筛选表达式中使用这些字段,具体方法如下。

有关参数的更多信息,请参阅 search()有关参数的更多信息,请参阅 SDK 参考资料中的

有关参数的更多信息,请参阅 search()有关参数的更多信息,请参阅 SDK 参考资料中的

有关参数的更多信息,请参阅 search()有关参数的更多信息,请参阅 SDK 参考资料中的

# 4. Search with dynamic fields
query_vectors = [[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]]

res = client.search(
collection_name="test_collection",
data=query_vectors,
filter="color in [\"red\", \"green\"]",
search_params={"metric_type": "L2", "params": {"nprobe": 10}},
limit=3
)

print(res)

# Output
#
# [
# [
# {
# "id": 863,
# "distance": 0.188413605093956,
# "entity": {
# "id": 863,
# "color_tag": "red_2371"
# }
# },
# {
# "id": 799,
# "distance": 0.29188022017478943,
# "entity": {
# "id": 799,
# "color_tag": "red_2235"
# }
# },
# {
# "id": 564,
# "distance": 0.3492690920829773,
# "entity": {
# "id": 564,
# "color_tag": "red_9186"
# }
# }
# ]
# ]

重述

值得注意的是,colortagcolor_tag在定义 Collection 模式时并不存在,但在进行搜索和查询时,可以将它们用作模式定义的字段。

如果非模式定义字段的名称包含数字、字母和下划线以外的字符,如加号 (+)、星号 (*) 或美元符号 ($),则在布尔表达式中使用该字段或将其包含在输出字段中时,必须将该键包含在**$meta[]**内,如以下代码片段所示。

...
filter='$meta["$key"] in ["a", "b", "c"]',
output_fields='$meta["$key"]'
...