JSON 索引
JSON 字段为在 Milvus 中存储结构化元数据提供了一种灵活的方式。如果没有索引,对 JSON 字段的查询需要全 Collection 扫描,随着数据集的增长,扫描速度也会变慢。JSON 索引通过在 JSON 数据中创建索引来实现快速查询。
JSON 索引适用于
具有一致、已知键的结构化 Schema
特定 JSON 路径上的等价和范围查询
需要精确控制索引键的情况
对目标查询进行高效存储加速
对于具有不同查询模式的复杂 JSON 文档,可考虑将JSON 切碎作为替代方案。
JSON 索引语法
创建 JSON 索引时,需要指定
JSON 路径:要索引的数据的确切位置
数据类型:如何解释和存储索引值
可选类型转换:如果需要,在索引过程中转换数据
下面是索引 JSON 字段的语法:
# Prepare index params
index_params = MilvusClient.prepare_index_params()
index_params.add_index(
field_name="<json_field_name>", # Name of the JSON field
index_type="AUTOINDEX", # Must be AUTOINDEX or INVERTED
index_name="<unique_index_name>", # Index name
params={
"json_path": "<path_to_json_key>", # Specific key to be indexed within JSON data
"json_cast_type": "<data_type>", # Data type to use when interpreting and indexing the value
# "json_cast_function": "<cast_function>" # Optional: convert key values into a target type at index time
}
)
参数 |
说明 |
值/示例 |
|---|---|---|
|
Collections Schema 中 JSON 字段的名称。 |
|
|
对于 JSON 索引,必须是 |
|
|
该索引的唯一标识符。 |
|
|
您希望在 JSON 对象中索引的键的路径。 |
|
|
解释和索引值时要使用的数据类型。必须与键的实际数据类型相匹配。 |
|
|
(可选)在索引时将原始键值转换为目标类型。只有当键值以错误的格式存储,且需要在索引过程中转换数据类型时,才需要使用此配置。 有关可用的转换函数列表,请参阅下面的支持的转换函数。 |
|
支持的数据类型
Milvus 支持以下数据类型在索引时进行转换。这些类型可确保正确解释数据,从而实现高效过滤。
数据类型 |
描述 |
示例 JSON 值 |
|---|---|---|
|
用于索引布尔值,以便根据真/假条件进行查询。 |
|
|
用于数值,包括整数和浮点数。它可以根据范围或相等条件进行筛选(如 |
|
|
用于索引字符串值,常见于基于文本的数据,如名称、类别或 ID。 |
|
|
用于索引布尔值数组。 |
|
|
用于索引数值数组。 |
|
|
用于索引字符串数组,是标签或关键字列表的理想选择。 |
|
|
整个 JSON 对象或子对象,具有自动类型推断和扁平化功能。 索引整个 JSON 对象会增加索引大小。对于多键情况,可考虑使用JSON Shredding。 |
任何 JSON 对象 |
数组应包含相同类型的元素,以优化索引。有关详细信息,请参阅数组字段。
支持的铸入函数
如果您的 JSON 字段键包含格式不正确的值(例如,以字符串形式存储的数字),您可以向json_cast_function 参数传递铸型函数,以便在索引时转换这些值。
转换函数不区分大小写。支持以下函数:
转换函数 |
转换自 → 转换为 |
使用案例 |
|---|---|---|
|
字符串 → 数值(双) |
将 |
如果转换失败(如非数字字符串),该值将被跳过,不会被索引。
创建 JSON 索引
本节通过实际示例演示如何在不同类型的 JSON 数据上创建索引。所有示例都使用了下图所示的 JSON 结构示例,并假设您已经建立了与MilvusClient的连接,并正确定义了 CollectionsSchema。
JSON 结构示例
{
"metadata": {
"category": "electronics",
"brand": "BrandA",
"in_stock": true,
"price": 99.99,
"string_price": "99.99",
"tags": ["clearance", "summer_sale"],
"supplier": {
"name": "SupplierX",
"country": "USA",
"contact": {
"email": "support@supplierx.com",
"phone": "+1-800-555-0199"
}
}
}
}
基本设置
在创建任何 JSON 索引之前,请准备好索引参数:
# Prepare index params
index_params = MilvusClient.prepare_index_params()
例 1:索引一个简单的 JSON 键
在category 字段上创建索引,以便按产品类别快速筛选:
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX", # Must be set to AUTOINDEX or INVERTED for JSON path indexing
index_name="category_index", # Unique index name
params={
"json_path": 'metadata["category"]', # Path to the JSON key
"json_cast_type": "varchar" # Data cast type
}
)
例 2:索引嵌套键
在深度嵌套的email 字段上创建索引,用于搜索供应商联系人:
# Index the nested key
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX", # Must be set to AUTOINDEX or INVERTED for JSON path indexing
index_name="email_index", # Unique index name
params={
"json_path": 'metadata["supplier"]["contact"]["email"]', # Path to the nested JSON key
"json_cast_type": "varchar" # Data cast type
}
)
例 3:索引时转换数据类型
有时,数字数据会被错误地存储为字符串。使用STRING_TO_DOUBLE 转换功能进行正确转换和索引:
# Convert string numbers to double for indexing
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX", # Must be set to AUTOINDEX or INVERTED for JSON path indexing
index_name="string_to_double_index", # Unique index name
params={
"json_path": 'metadata["string_price"]', # Path to the JSON key to be indexed
"json_cast_type": "double", # Data cast type
"json_cast_function": "STRING_TO_DOUBLE" # Cast function; case insensitive
}
)
重要: 如果任何文档的转换失败(例如,非数字字符串,如"invalid" ),该文档的值将被排除在索引之外,不会出现在筛选结果中。
示例 4:索引整个对象
索引整个 JSON 对象,以便对其中的任何字段进行查询。使用json_cast_type="JSON" 时,系统会自动
使 JSON 结构扁平化:将嵌套对象转换为扁平路径,以实现高效索引
推断数据类型:根据每个值的内容自动将其归类为数值、字符串、布尔值或日期值
创建全面的覆盖范围:对象中的所有键和嵌套路径均可搜索
对于上述示例 JSON 结构,可对整个metadata 对象进行索引:
# Index the entire JSON object
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX",
index_name="metadata_full_index",
params={
"json_path": "metadata",
"json_cast_type": "JSON"
}
)
您也可以只索引 JSON 结构的一部分,例如所有supplier 信息:
# Index a sub-object
index_params.add_index(
field_name="metadata",
index_type="AUTOINDEX",
index_name="supplier_index",
params={
"json_path": 'metadata["supplier"]',
"json_cast_type": "JSON"
}
)
应用索引配置
定义好所有索引参数后,将其应用到 Collections 中:
# Apply all index configurations to the collection
MilvusClient.create_index(
collection_name="your_collection_name",
index_params=index_params
)
索引完成后,您的 JSON 字段查询将自动使用这些索引,以提高性能。
常见问题
如果查询的过滤表达式使用的类型与索引的铸型类型不同,会发生什么情况?
如果你的过滤表达式使用的类型与索引的json_cast_type 不同,Milvus 将不会使用索引,如果数据允许,可能会退回到较慢的暴力扫描。为获得最佳性能,请始终将过滤表达式与索引的铸型类型保持一致。例如,如果使用json_cast_type="double" 创建了数字索引,则只有数字过滤条件会利用该索引。
创建 JSON 索引时,如果不同实体的 JSON 键的数据类型不一致怎么办?
不一致的类型会导致部分索引。例如,如果metadata["price"] 字段同时以数字(99.99 )和字符串("99.99" )的形式存储,并且您使用json_cast_type="double" 创建了索引,那么只有数字值会被索引。字符串形式的条目将被跳过,不会出现在过滤结果中。
能否在同一个 JSON 关键字上创建多个索引?
不能,每个 JSON 关键字只支持一个索引。您必须选择一个与您的数据相匹配的json_cast_type 。不过,您可以为整个 JSON 对象创建索引,也可以为该对象中的嵌套键创建索引。
JSON 字段是否支持设置默认值?
不,JSON 字段不支持默认值。不过,您可以在定义字段时设置nullable=True ,以允许空条目。有关详细信息,请参阅 "可为空和默认值"。