当前位置: 首页 > news >正文

Milvus(11):动态字段、可归零和默认值

1 动态字段

        Collections 的 Schema 中定义的所有字段都必须包含在要插入的实体中。如果希望某些字段是可选的,可以考虑启用动态字段。

1.1 概述

        在 Milvus 中,可以通过设置 Collections 中每个字段的名称和数据类型来创建 Collections Schema。向 Schema 中添加字段时,请确保该字段包含在要插入的实体中。如果希望某些字段是可选的,启用动态字段是一种选择。

        动态字段是一个名为$meta 的保留字段,属于 JavaScript Object Notation(JSON)类型。实体中任何未在 Schema 中定义的字段都将以键值对的形式存储在这个保留的 JSON 字段中。对于启用了动态字段的 Collections,可以使用动态字段中的键进行标量过滤,就像使用模式中明确定义的字段一样。

1.2 启用动态字段

        使用 "即时创建集合"中描述的方法创建的集合默认已启用动态字段。也可以在创建具有自定义设置的 Collections 时手动启用动态字段。

from pymilvus import MilvusClientclient= MilvusClient(uri="http://localhost:19530")client.create_collection(collection_name="my_collection",dimension=5,# highlight-next-lineenable_dynamic_field=True
)

1.3 使用动态字段

        当在 Collections 中启用动态字段时,所有未在 Schema 中定义的字段及其值都将作为键值对存储在动态字段中。例如,假设您的 Collections Schema 只定义了两个字段,名为id 和vector ,并启用了动态字段。现在,在此 Collections 中插入以下数据集。

[{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"}        
]

        上面的数据集包含 10 个实体,每个实体都包括字段id,vector, 和color 。这里,Schema 中没有定义color 字段。由于 Collections 启用了动态字段,因此字段color 将作为键值对存储在动态字段中。

1.3.1 插入数据

        以下代码演示了如何将此数据集插入 Collections。

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="my_collection",data=data
)print(res)# Output
# {'insert_count': 10, 'ids': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}

1.3.2 在动态字段中索引标量字段

        启用动态字段后,任何未定义的标量字段都会以 JSON 格式存储为键值对。Milvus 支持在这种未定义的标量字段上创建索引,有效的方法是建立一个 JSON 路径索引。具体操作如下

  1. 选择要索引的 Dynamic Field 关键字。例如,上例中的"color" 。

  2. 为在该关键字中找到的值决定一个铸模类型。Milvus 将解析动态字段,提取指定键下的值,并将它们转换为你配置的类型。

    • 支持的json_cast_type 值有bool (或BOOL )、double (或DOUBLE )和varchar (或VARCHAR )。

    • 如果解析或转换失败(例如,试图将字符串解析为 double),索引将跳过这些行。

  3. 将该键的JSON 路径指定json_path 。由于动态字段是以 JSON 格式存储的,因此可以指定类似"color" 这样的路径,如果有嵌套结构,则可以指定更深的路径(例如my_json["field"]["subfield"] )。

  4. 创建 INVERTED 索引。目前,JSON 路径索引只支持INVERTED 类型。

        下面是如何在"color" 字段上创建索引的示例:

# 准备索引参数
index_params = client.prepare_index_params()index_params.add_index(field_name="color",               # 在查询中看到的“列”的名称(动态键)。index_type="INVERTED",            # 目前,JSON字段的索引只支持“INVERTED”。index_name="color_index",         # 为这个索引指定一个名称。params={"json_path": "color",         # 要索引的键的JSON路径。"json_cast_type": "varchar"   # Milvus将将提取的值强制转换到的类型。}
)# Create the index
client.create_index(collection_name="my_collection",index_params=index_params
)

1.3.3 使用动态字段进行查询和搜索

        Milvus 支持在查询和搜索过程中使用过滤表达式,允许您指定在结果中包含哪些字段。下面的示例演示了如何通过动态字段使用color 字段执行查询和搜索,该字段在 Schema 中没有定义。

query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]res = client.search(collection_name="my_collection",data=[query_vector],limit=5,# highlight-startfilter='color like "red%"',output_fields=["color"]# highlight-end
)print(res)# Output
# data: ["[{'id': 1, 'distance': 0.6290165185928345, 'entity': {'color': 'red_7025'}}, {'id': 4, 'distance': 0.5975797176361084, 'entity': {'color': 'red_4794'}}, {'id': 6, 'distance': -0.24996188282966614, 'entity': {'color': 'red_9392'}}]"] 

        在上面代码示例中使用的过滤表达式color like "red%" and likes > 50 中,条件指定color 字段的值必须以"红色 "开头。

[{"id": 1, "distance": 0.6290165,"entity": {"color": "red_7025"}},{"id": 4, "distance": 0.5975797,"entity": {"color": "red_4794"}},{"id": 6, "distance": -0.24996188,"entity": {"color": "red_9392"}},
]

2 可归零和默认值

        Milvus 允许你为标量字段(主字段除外)设置nullable 属性和默认值。对于标记为nullable=True 的字段,您可以在插入数据时跳过该字段,或直接将其设置为空值,系统会将其视为空值而不会导致错误。当字段具有默认值时,如果在插入过程中没有为该字段指定数据,系统将自动应用该值。

        默认值和可归零属性允许处理带有空值的数据集并保留默认值设置,从而简化了从其他数据库系统到 Milvus 的数据迁移。在创建 Collections 时,也可以启用可归零属性或为可能存在不确定值的字段设置默认值。

2.1 限制

  • 只有标量字段(主字段除外)支持默认值和 nullable 属性。
  • JSON 和数组字段不支持默认值。
  • 默认值或 nullable 属性只能在创建 Collections 时配置,之后不能修改。
  • 启用了可归零属性的标量字段不能在分组搜索中用作group_by_field 。
  • 标记为可归零的字段不能用作分区键。
  • 在启用了可归零属性的标量字段上创建索引时,索引将排除空值。
  • JSON 和 ARRAY 字段:当使用IS NULL 或IS NOT NULL 操作符对 JSON 或 ARRAY 字段进行筛选时,这些操作符在列级别工作,这表明它们只评估整个 JSON 对象或数组是否为空。例如,如果 JSON 对象中的某个键为空,IS NULL 过滤器将无法识别该键。

2.2 Nullable 属性

        通过nullable 属性,可以在 Collections 中存储空值,从而在处理未知数据时提供灵活性。

2.2.1 设置 nullable 属性

        创建 Collections 时,使用nullable=True 定义可归零字段(默认为False )。下面的示例创建了一个名为my_collection 的 Collection,并将age 字段设置为可归零:

from pymilvus import MilvusClient, DataTypeclient = MilvusClient(uri='http://localhost:19530')# 定义集合模式
schema = client.create_schema(auto_id=False,enable_dynamic_schema=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)
schema.add_field(field_name="age", datatype=DataType.INT64, nullable=True) # 可空字段# 设置索引参数
index_params = client.prepare_index_params()
index_params.add_index(field_name="vector", index_type="AUTOINDEX", metric_type="L2")# 创建集合
client.create_collection(collection_name="my_collection", schema=schema, index_params=index_params)

2.2.2 插入实体

        在可空字段中插入数据时,插入空值或直接省略该字段:

data = [{"id": 1, "vector": [0.1, 0.2, 0.3, 0.4, 0.5], "age": 30},{"id": 2, "vector": [0.2, 0.3, 0.4, 0.5, 0.6], "age": None},{"id": 3, "vector": [0.3, 0.4, 0.5, 0.6, 0.7]}
]client.insert(collection_name="my_collection", data=data)

2.2.3 使用空值进行搜索和查询

        使用search 方法时,如果字段包含null 值,则搜索结果将以空值返回该字段:

res = client.search(collection_name="my_collection",data=[[0.1, 0.2, 0.4, 0.3, 0.128]],limit=2,search_params={"params": {"nprobe": 16}},output_fields=["id", "age"]
)print(res)# Output
# data: ["[{'id': 1, 'distance': 0.15838398039340973, 'entity': {'age': 30, 'id': 1}}, {'id': 2, 'distance': 0.28278401494026184, 'entity': {'age': None, 'id': 2}}]"] 

        当您使用query 方法进行标量过滤时,空值的过滤结果都是 false,表示不会选择它们。

# 查看先前插入的数据:
# {"id": 1, "vector": [0.1, 0.2, ..., 0.128], "age": 30}
# {"id": 2, "vector": [0.2, 0.3, ..., 0.129], "age": None}
# {"id": 3, "vector": [0.3, 0.4, ..., 0.130], "age": None}  # 省略的age列被视为None
results = client.query(collection_name="my_collection",filter="age >= 0",output_fields=["id", "age"]
)# Example output:
# [
#     {"id": 1, "age": 30}
# ]
# Note: ‘ age ’为‘ null ’ (id 2和3)的实体将不会出现在结果中。

        要返回具有null 值的实体,可在不使用任何标量过滤条件的情况下进行如下查询,query 方法在不带任何过滤条件的情况下使用时,会检索 Collections 中的所有实体,包括具有空值的实体。要限制返回实体的数量,必须指定limit 参数。

null_results = client.query(collection_name="my_collection",filter="",     # 不带任何过滤条件的查询output_fields=["id", "age"],limit=10
)# Example output:
# [{"id": 2, "age": None}, {"id": 3, "age": None}]

2.3 默认值

        默认值是分配给标量字段的预设值。如果在插入时没有为有默认值的字段提供值,系统会自动使用默认值。

2.3.1 设置默认值

        创建 Collections 时,使用default_value 参数定义字段的默认值。下面的示例显示了如何将age 的默认值设置为18 ,将status 的默认值设置为"active" :

schema = client.create_schema(auto_id=False,enable_dynamic_schema=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)
schema.add_field(field_name="age", datatype=DataType.INT64, default_value=18)
schema.add_field(field_name="status", datatype=DataType.VARCHAR, default_value="active", max_length=10)index_params = client.prepare_index_params()
index_params.add_index(field_name="vector", index_type="AUTOINDEX", metric_type="L2")client.create_collection(collection_name="my_collection", schema=schema, index_params=index_params)

2.3.2 插入实体

        插入数据时,如果省略有默认值的字段或将其值设为空,系统就会使用默认值:

data = [{"id": 1, "vector": [0.1, 0.2, ..., 0.128], "age": 30, "status": "premium"},{"id": 2, "vector": [0.2, 0.3, ..., 0.129]},  # ‘ age ’和‘ status ’使用默认值{"id": 3, "vector": [0.3, 0.4, ..., 0.130], "age": 25, "status": None},  # “status”使用默认值{"id": 4, "vector": [0.4, 0.5, ..., 0.131], "age": None, "status": "inactive"}  # ‘ age ’使用默认值
]client.insert(collection_name="my_collection", data=data)

2.3.3 使用默认值进行搜索和查询

        在向量搜索和标量过滤过程中,包含默认值的实体与其他实体的处理方式相同。您可以将默认值作为search 和query 操作符的一部分。例如,在search 操作符中,将age 设置为默认值18 的实体将包含在结果中:

res = client.search(collection_name="my_collection",data=[[0.1, 0.2, 0.4, 0.3, 0.5]],search_params={"params": {"nprobe": 16}},filter="age == 18",  # “age”字段的默认值为18limit=10,output_fields=["id", "age", "status"]
)print(res)# Output
# data: ["[{'id': 2, 'distance': 0.050000004, 'entity': {'id': 2, 'age': 18, 'status': 'active'}}, {'id': 4, 'distance': 0.45000002, 'entity': {'id': 4, 'age': 18, 'status': 'inactive'}}]"] 

        在query 操作符中,可以直接通过默认值进行匹配或过滤:

# 查询‘ age ’等于默认值(18)的所有实体
default_age_results = client.query(collection_name="my_collection",filter="age == 18",output_fields=["id", "age", "status"]
)# 查询“status”等于默认值(“active”)的所有实体
default_status_results = client.query(collection_name="my_collection",filter='status == "active"',output_fields=["id", "age", "status"]
)

2.3.4 适用规则

        下表总结了可空列和默认值在不同配置组合下的行为。这些规则决定了 Milvus 在尝试插入空值或未提供字段值时如何处理数据。

可归零

默认值

默认值类型

用户输入

结果

示例

非空

无/空

使用默认值

字段: age 默认值:18

用户输入:空

结果:存储为18

-

无/空

存储为空

字段: middle_name 默认值: -

用户输入:空

结果:存储为空

非空

无/空

使用默认值

字段: status 默认值:"active"

用户输入:空

结果:存储为"active"

-

无/空

抛出错误

字段: email 默认值:-

用户输入:空

结果:操作被拒绝,系统提示错误

无/空

抛出错误

字段: username 默认值:空

用户输入:空

结果:操作符被拒绝,系统提示错误

http://www.xdnf.cn/news/227143.html

相关文章:

  • 基于开源AI智能名片链动2+1模式S2B2C商城小程序的私域电商与微商融合创新研究
  • 基于Docker的Elasticsearch ARM64架构镜像构建实践
  • vue 和 html 的区别
  • 20250430在ubuntu14.04.6系统上查看系统实时网速
  • 运营岗位选择
  • 多用户远程 Debugger 服务隔离方案技术实践
  • Java使用 MyBatis-Plus 实现前端组装查询语句、后端动态执行查询的功能,
  • 使用vue开发electron
  • Git从入门到精通-第二章-工具配置
  • 软考中级-软件设计师 数据结构(手写笔记)
  • 文献分享:CovEpiAb-冠状病毒免疫表位及抗体数据库
  • HCIP-数据通信datacom认证
  • 【RustDesk 】中继1:压力测试 Python 版 RustDesk 中继服务器
  • 【安全扫描器原理】基于协议的服务扫描器
  • 欧洲分子生物学实验室EMBL介绍
  • 详解具身智能机器人开源数据集:RoboMIND
  • 数字孪生技术十大创新应用场景与工程实践
  • Vue3 Echarts 3D立方体柱状图实现教程
  • 碰一碰发视频源码||客户端开发实战:NFC+低延迟传输技术实现引言
  • 【每日八股】复习 Redis Day3:Redis 的应用
  • 电脑干货:开源免费的QQ空间说说下载工具GetQzonehistory
  • 海外社交软件开发进阶:AI驱动与高可用架构的深度实践
  • Unity3D仿星露谷物语开发40之割草动画
  • 32单片机——独立看门狗
  • OpenCV 图形API(74)图像与通道拼接函数-----合并三个单通道图像(GMat)为一个多通道图像的函数merge3()
  • 前端技巧——性能优化篇
  • 哪些因素会影响远程视频监控的质量?浅述EasyCVR视频智能诊断技术
  • 【AI平台】n8n入门5:创建MCP服务,及vscode调用MCP测试
  • Spring AOP概念及其实现
  • uniapp如何获取安卓原生的Intent对象