milvus-logo
LFAI
首页
  • 用户指南

使用 JSON 字段

本指南介绍如何使用 JSON 字段,例如插入 JSON 值以及使用基本和高级操作符在 JSON 字段中进行搜索和查询。

概述

JSON 是 Javascript Object Notation 的缩写,是一种基于文本的轻量级简单数据格式。JSON 中的数据采用键值对结构,其中每个键都是一个字符串,可映射到数字、字符串、布尔、列表或数组的值。使用 Milvus 群集,可以将字典作为字段值存储在集合中。

例如,以下代码会随机生成键值对,每个键值对都包含一个键值为颜色的 JSON 字段。

# 3. Insert randomly generated vectors 
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)
    current_coord = [ random.randint(0, 40) for _ in range(3) ]
    current_ref = [ [ random.choice(colors) for _ in range(3) ] for _ in range(3) ]
    data.append({
        "id": i,
        "vector": [ random.uniform(-1, 1) for _ in range(5) ],
        "color": {
            "label": current_color,
            "tag": current_tag,
            "coord": current_coord,
            "ref": current_ref
        }
    })

print(data[0])
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Random;

import com.alibaba.fastjson.JSONObject;

// 3. Insert randomly generated vectors and JSON data into the collection
List<String> colors = Arrays.asList("green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey");
List<JSONObject> data = new ArrayList<>();

for (int i=0; i<1000; i++) {
    Random rand = new Random();
    String current_color = colors.get(rand.nextInt(colors.size()-1));
    Integer current_tag = rand.nextInt(8999) + 1000;
    List<Integer> current_coord = Arrays.asList(rand.nextInt(40), rand.nextInt(40), rand.nextInt(40));
    List<List<String>> current_ref = Arrays.asList(
        Arrays.asList(colors.get(rand.nextInt(colors.size()-1)), colors.get(rand.nextInt(colors.size()-1)), colors.get(rand.nextInt(colors.size()-1))),
        Arrays.asList(colors.get(rand.nextInt(colors.size()-1)), colors.get(rand.nextInt(colors.size()-1)), colors.get(rand.nextInt(colors.size()-1))),
        Arrays.asList(colors.get(rand.nextInt(colors.size()-1)), colors.get(rand.nextInt(colors.size()-1)), colors.get(rand.nextInt(colors.size()-1)))
    );
    JSONObject row = new JSONObject();
    row.put("id", Long.valueOf(i));
    row.put("vector", Arrays.asList(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat()));
    JSONObject color = new JSONObject();
    color.put("label", current_color);
    color.put("tag", current_tag);
    color.put("coord", current_coord);
    color.put("ref", current_ref);
    row.put("color", color);
    data.add(row);
}

System.out.println(JSONObject.toJSON(data.get(0)));   
// 3. Insert randomly generated vectors 
const colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"]
var data = []

for (let i = 0; i < 1000; i++) {
    const current_color = colors[Math.floor(Math.random() * colors.length)]
    const current_tag = Math.floor(Math.random() * 8999 + 1000)
    const current_coord = Array(3).fill(0).map(() => Math.floor(Math.random() * 40))
    const current_ref = [ Array(3).fill(0).map(() => colors[Math.floor(Math.random() * colors.length)]) ]

    data.push({
        id: i,
        vector: [Math.random(), Math.random(), Math.random(), Math.random(), Math.random()],
        color: {
            label: current_color,
            tag: current_tag,
            coord: current_coord,
            ref: current_ref
        }
    })
}

console.log(data[0])

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

{
    "id": 0,
    "vector": [
        -0.8017921296923975,
        0.550046715206634,
        0.764922589768134,
        0.6371433836123146,
        0.2705233937454232
    ],
    "color": {
        "label": "blue",
        "tag": 9927,
        "coord": [
            22,
            36,
            6
        ],
        "ref": [
            [
                "blue",
                "green",
                "white"
            ],
            [
                "black",
                "green",
                "pink"
            ],
            [
                "grey",
                "black",
                "brown"
            ]
        ]
    }
}

注意事项

  • 确保列表或数组中的所有值都是相同的数据类型。

  • JSON 字段值中的任何嵌套字典都将被视为字符串。

  • 仅使用字母数字字符和下划线来命名 JSON 键,因为其他字符可能会导致过滤或搜索出现问题。

  • 目前,还不能为 JSON 字段编制索引,这可能会导致过滤耗时。不过,这一限制将在即将发布的版本中得到解决。

定义 JSON 字段

要定义 JSON 字段,只需遵循与定义其他类型字段相同的步骤即可。

有关参数的更多信息,请参阅 MilvusClient, create_schema(), add_field(), add_index(), create_collection()get_load_state()在 SDK 参考资料中。

有关参数的更多信息,请参阅 MilvusClientV2, createSchema(), addField(), IndexParam, createCollection()getLoadState()在 SDK 参考资料中。

有关参数的更多信息,请参阅 MilvusClientcreateCollection()createCollection()

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

CLUSTER_ENDPOINT = "http://localhost:19530"

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

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

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="color", datatype=DataType.JSON)

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>"
# }
String CLUSTER_ENDPOINT = "http://localhost:19530";

// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
    .uri(CLUSTER_ENDPOINT)
    .build();

MilvusClientV2 client = new MilvusClientV2(connectConfig);

// 2. Create a collection in customized setup mode

// 2.1 Create schema
CreateCollectionReq.CollectionSchema schema = client.createSchema();

// 2.2 Add fields to schema
schema.addField(AddFieldReq.builder()
    .fieldName("id")
    .dataType(DataType.Int64)
    .isPrimaryKey(true)
    .autoID(false)
    .build());

schema.addField(AddFieldReq.builder()
    .fieldName("vector")
    .dataType(DataType.FloatVector)
    .dimension(5)
    .build());

schema.addField(AddFieldReq.builder()
    .fieldName("color")
    .dataType(DataType.JSON)
    .build());

// 2.3 Prepare index parameters
IndexParam indexParamForIdField = IndexParam.builder()
    .fieldName("id")
    .indexType(IndexParam.IndexType.STL_SORT)
    .build();

IndexParam indexParamForVectorField = IndexParam.builder()
    .fieldName("vector")
    .indexType(IndexParam.IndexType.IVF_FLAT)
    .metricType(IndexParam.MetricType.IP)
    .extraParams(Map.of("nlist", 1024))
    .build();

List<IndexParam> indexParams = new ArrayList<>();
indexParams.add(indexParamForIdField);
indexParams.add(indexParamForVectorField);

// 2.4 Create a collection with schema and index parameters
CreateCollectionReq customizedSetupReq = CreateCollectionReq.builder()
    .collectionName("test_collection")
    .collectionSchema(schema)
    .indexParams(indexParams)         
    .build();

client.createCollection(customizedSetupReq);

// 2.5 Check if the collection is loaded
GetLoadStateReq getLoadStateReq = GetLoadStateReq.builder()
    .collectionName("test_collection")
    .build();

Boolean isLoaded = client.getLoadState(getLoadStateReq);

System.out.println(isLoaded);

// Output:
// true
const { MilvusClient, DataType, sleep } = require("@zilliz/milvus2-sdk-node")

const address = "http://localhost:19530"

async function main() {
// 1. Set up a Milvus Client
client = new MilvusClient({address}); 

// 2. Create a collection
// 2.1 Define fields
const fields = [
    {
        name: "id",
        data_type: DataType.Int64,
        is_primary_key: true,
        auto_id: false
    },
    {
        name: "vector",
        data_type: DataType.FloatVector,
        dim: 5
    },
    {
        name: "color",
        data_type: DataType.JSON,
    }
]

// 2.2 Prepare index parameters
const index_params = [{
    field_name: "vector",
    index_type: "IVF_FLAT",
    metric_type: "IP",
    params: { nlist: 1024}
}]

// 2.3 Create a collection with fields and index parameters
res = await client.createCollection({
    collection_name: "test_collection",
    fields: fields, 
    index_params: index_params
})

console.log(res.error_code)

// Output
// 
// Success
// 

res = await client.getLoadState({
    collection_name: "test_collection",
})  

console.log(res.state)

// Output
// 
// LoadStateLoaded
// 

有关参数的更多信息,请参阅 MilvusClient, create_schema(), add_field(), add_index(), create_collection()get_load_state()在 SDK 参考资料中。

有关参数的更多信息,请参阅 MilvusClientV2, createSchema(), addField(), IndexParam, createCollection()getLoadState()在 SDK 参考资料中。

有关参数的更多信息,请参阅 MilvusClient, createCollection()getLoadState()的更多信息。

插入字段值

CollectionSchema 对象创建一个 Collection 后,就可以向其中插入字典,如上面的字典。

使用 insert()方法将数据插入到集合中。

使用 insert()方法将数据插入 Collection。

使用 insert()方法将数据插入 Collections。

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)"
#     ]
# }
// 3.1 Insert data into the collection
InsertReq insertReq = InsertReq.builder()
    .collectionName("test_collection")
    .data(data)
    .build();

InsertResp insertResp = client.insert(insertReq);

System.out.println(JSONObject.toJSON(insertResp));

// Output:
// {"insertCnt": 1000}
// 3. Insert randomly generated vectors 
const colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"]
var data = []

for (let i = 0; i < 1000; i++) {
    const current_color = colors[Math.floor(Math.random() * colors.length)]
    const current_tag = Math.floor(Math.random() * 8999 + 1000)
    const current_coord = Array(3).fill(0).map(() => Math.floor(Math.random() * 40))
    const current_ref = [ Array(3).fill(0).map(() => colors[Math.floor(Math.random() * colors.length)]) ]

    data.push({
        id: i,
        vector: [Math.random(), Math.random(), Math.random(), Math.random(), Math.random()],
        color: {
            label: current_color,
            tag: current_tag,
            coord: current_coord,
            ref: current_ref
        }
    })
}

console.log(data[0])

// Output
// 
// {
//   id: 0,
//   vector: [
//     0.11455530974226114,
//     0.21704086958595314,
//     0.9430119822312437,
//     0.7802712923612023,
//     0.9106927960926137
//   ],
//   color: { label: 'grey', tag: 7393, coord: [ 22, 1, 22 ], ref: [ [Array] ] }
// }
// 

res = await client.insert({
    collection_name: "test_collection",
    data: data,
})

console.log(res.insert_cnt)

// Output
// 
// 1000
// 

基本标量过滤

一旦添加了所有数据,就可以使用 JSON 字段中的键进行搜索和查询,方法与标准标量字段相同。

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

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

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

# 4. Basic search with a JSON field
query_vectors = [ [ random.uniform(-1, 1) for _ in range(5) ]]

res = client.search(
    collection_name="test_collection",
    data=query_vectors,
    filter='color["label"] in ["red"]',
    search_params={
        "metric_type": "L2",
        "params": {"nprobe": 16}
    },
    output_fields=["id", "color"],
    limit=3
)

print(res)

# Output
#
# [
#     [
#         {
#             "id": 460,
#             "distance": 0.4016231596469879,
#             "entity": {
#                 "id": 460,
#                 "color": {
#                     "label": "red",
#                     "tag": 5030,
#                     "coord": [14, 32, 40],
#                     "ref": [
#                         [ "pink", "green", "brown" ],
#                         [ "red", "grey", "black"],
#                         [ "red", "yellow", "orange"]
#                     ]
#                 }
#             }
#         },
#         {
#             "id": 785,
#             "distance": 0.451080858707428,
#             "entity": {
#                 "id": 785,
#                 "color": {
#                     "label": "red",
#                     "tag": 5290,
#                     "coord": [31, 13, 23],
#                     "ref": [
#                         ["yellow", "pink", "pink"],
#                         ["purple", "grey", "orange"],
#                         ["grey", "purple", "pink"]
#                     ]
#                 }
#             }
#         },
#         {
#             "id": 355,
#             "distance": 0.5839247703552246,
#             "entity": {
#                 "id": 355,
#                 "color": {
#                     "label": "red",
#                     "tag": 8725,
#                     "coord": [5, 10, 22],
#                     "ref": [
#                         ["white", "purple", "yellow"],
#                         ["white", "purple", "white"],
#                         ["orange", "white", "pink"]
#                     ]
#                 }
#             }
#         }
#     ]
# ]
// 4. Basic search with a JSON field
List<List<Float>> query_vectors = Arrays.asList(Arrays.asList(0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f));

SearchReq searchReq = SearchReq.builder()
    .collectionName("test_collection")
    .data(query_vectors)
    .filter("color[\"label\"] in [\"red\"]")
    .outputFields(Arrays.asList("id", "color"))
    .topK(3)
    .build();

SearchResp searchResp = client.search(searchReq);

System.out.println(JSONObject.toJSON(searchResp));

// Output:
// {"searchResults": [[
//     {
//         "distance": 1.2636482,
//         "id": 290,
//         "entity": {
//             "color": {
//                 "coord": [32,37,32],
//                 "ref": [
//                     ["green", "blue", "yellow"],
//                     ["yellow", "pink", "pink"],
//                     ["purple", "red", "brown"]
//                 ],
//                 "label": "red",
//                 "tag": 8949
//             },
//             "id": 290
//         }
//     },
//     {
//         "distance": 1.002122,
//         "id": 629,
//         "entity": {
//             "color": {
//                 "coord": [23,5,35],
//                 "ref": [
//                     ["black", ""yellow", "black"],
//                     ["black", "purple", "white"],
//                     ["black", "brown", "orange"]
//                 ],
//                 "label": "red",
//                 "tag": 5072
//             },
//             "id": 629
//         }
//     },
//     {
//         "distance": 0.9542817,
//         "id": 279,
//         "entity": {
//             "color": {
//                 "coord": [20,33,33],
//                 "ref": [
//                     ["yellow", "white", "brown"],
//                     ["black", "white", "purple"],
//                     ["green", "brown", "blue"]
//                 ],
//                 "label": "red",
//                 "tag": 4704
//             },
//             "id": 279
//         }
//     }
// ]]}
// 4. Basic search with a JSON field
query_vectors = [[0.6765405125697714, 0.759217474274025, 0.4122471841491111, 0.3346805565394215, 0.09679748345514638]]

res = await client.search({
    collection_name: "test_collection",
    data: query_vectors,
    filter: 'color["label"] in ["red"]',
    output_fields: ["color", "id"],
    limit: 3
})

console.log(JSON.stringify(res.results, null, 4))

// Output
// 
// [
//     {
//         "score": 1.777988076210022,
//         "id": "595",
//         "color": {
//             "label": "red",
//             "tag": 7393,
//             "coord": [31,34,18],
//             "ref": [
//                 ["grey", "white", "orange"]
//             ]
//         }
//     },
//     {
//         "score": 1.7542595863342285,
//         "id": "82",
//         "color": {
//             "label": "red",
//             "tag": 8636,
//             "coord": [4,37,29],
//             "ref": [
//                 ["brown", "brown", "pink"]
//             ]
//         }
//     },
//     {
//         "score": 1.7537562847137451,
//         "id": "748",
//         "color": {
//             "label": "red",
//             "tag": 1626,
//             "coord": [31,4,25
//             ],
//             "ref": [
//                 ["grey", "green", "blue"]
//             ]
//         }
//     }
// ]
// 

高级标量过滤

Milvus 提供一组高级过滤器,用于在 JSON 字段中进行标量过滤。这些过滤器是JSON_CONTAINS,JSON_CONTAINS_ALL, 和JSON_CONTAINS_ANY

  • 过滤以["blue", "brown", "grey"] 作为参考颜色集的所有实体。

    # 5. Advanced search within a JSON field
    
    res = client.query(
        collection_name="test_collection",
        data=query_vectors,
        filter='JSON_CONTAINS(color["ref"], ["blue", "brown", "grey"])',
        output_fields=["id", "color"],
        limit=3
    )
    
    print(res)
    
    # Output
    #
    # [
    #     {
    #         "id": 79,
    #         "color": {
    #             "label": "orange",
    #             "tag": 8857,
    #             "coord": [
    #                 10,
    #                 14,
    #                 5
    #             ],
    #             "ref": [
    #                 [
    #                     "yellow",
    #                     "white",
    #                     "green"
    #                 ],
    #                 [
    #                     "blue",
    #                     "purple",
    #                     "purple"
    #                 ],
    #                 [
    #                     "blue",
    #                     "brown",
    #                     "grey"
    #                 ]
    #             ]
    #         }
    #     },
    #     {
    #         "id": 371,
    #         "color": {
    #             "label": "black",
    #             "tag": 1324,
    #             "coord": [
    #                 2,
    #                 18,
    #                 32
    #             ],
    #             "ref": [
    #                 [
    #                     "purple",
    #                     "orange",
    #                     "brown"
    #                 ],
    #                 [
    #                     "blue",
    #                     "brown",
    #                     "grey"
    #                 ],
    #                 [
    #                     "purple",
    #                     "blue",
    #                     "blue"
    #                 ]
    #             ]
    #         }
    #     },
    #     {
    #         "id": 590,
    #         "color": {
    #             "label": "red",
    #             "tag": 3340,
    #             "coord": [
    #                 13,
    #                 21,
    #                 13
    #             ],
    #             "ref": [
    #                 [
    #                     "yellow",
    #                     "yellow",
    #                     "red"
    #                 ],
    #                 [
    #                     "blue",
    #                     "brown",
    #                     "grey"
    #                 ],
    #                 [
    #                     "pink",
    #                     "yellow",
    #                     "purple"
    #                 ]
    #             ]
    #         }
    #     }
    # ]
    
    // 5. Advanced search within a JSON field
    searchReq = SearchReq.builder()
        .collectionName("test_collection")
        .data(query_vectors)
        .filter("JSON_CONTAINS(color[\"ref\"], [\"purple\", \"pink\", \"orange\"])")
        .outputFields(Arrays.asList("id", "color"))
        .topK(3)
        .build();
    
    searchResp = client.search(searchReq);
    
    System.out.println(JSONObject.toJSON(searchResp));
    
    // Output:
    // {"searchResults": [[
    //     {
    //         "distance": 1.1811467,
    //         "id": 180,
    //         "entity": {
    //             "color": {
    //                 "coord": [
    //                     17,
    //                     26,
    //                     14
    //                 ],
    //                 "ref": [
    //                     [
    //                         "white",
    //                         "black",
    //                         "brown"
    //                     ],
    //                     [
    //                         "purple",
    //                         "pink",
    //                         "orange"
    //                     ],
    //                     [
    //                         "black",
    //                         "pink",
    //                         "red"
    //                     ]
    //                 ],
    //                 "label": "green",
    //                 "tag": 2470
    //             },
    //             "id": 180
    //         }
    //     },
    //     {
    //         "distance": 0.6487204,
    //         "id": 331,
    //         "entity": {
    //             "color": {
    //                 "coord": [
    //                     16,
    //                     32,
    //                     23
    //                 ],
    //                 "ref": [
    //                     [
    //                         "purple",
    //                         "pink",
    //                         "orange"
    //                     ],
    //                     [
    //                         "brown",
    //                         "red",
    //                         "orange"
    //                     ],
    //                     [
    //                         "red",
    //                         "yellow",
    //                         "brown"
    //                     ]
    //                 ],
    //                 "label": "white",
    //                 "tag": 1236
    //             },
    //             "id": 331
    //         }
    //     },
    //     {
    //         "distance": 0.59387654,
    //         "id": 483,
    //         "entity": {
    //             "color": {
    //                 "coord": [
    //                     8,
    //                     33,
    //                     2
    //                 ],
    //                 "ref": [
    //                     [
    //                         "red",
    //                         "orange",
    //                         "brown"
    //                     ],
    //                     [
    //                         "purple",
    //                         "pink",
    //                         "orange"
    //                     ],
    //                     [
    //                         "brown",
    //                         "blue",
    //                         "green"
    //                     ]
    //                 ],
    //                 "label": "pink",
    //                 "tag": 5686
    //             },
    //             "id": 483
    //         }
    //     }
    // ]]}
    
    // 5. Advanced search within a JSON field
    res = await client.search({
        collection_name: "test_collection",
        data: query_vectors,
        filter: 'JSON_CONTAINS(color["ref"], ["blue", "brown", "grey"])',
        output_fields: ["color", "id"],
        limit: 3
    })
    
    console.log(JSON.stringify(res.results, null, 4))
    
    // Output
    // 
    // [
    //     {
    //         "id": 79,
    //         "color": {
    //             "label": "orange",
    //             "tag": 8857,
    //             "coord": [
    //                 10,
    //                 14,
    //                 5
    //             ],
    //             "ref": [
    //                 [
    //                     "yellow",
    //                     "white",
    //                     "green"
    //                 ],
    //                 [
    //                     "blue",
    //                     "purple",
    //                     "purple"
    //                 ],
    //                 [
    //                     "blue",
    //                     "brown",
    //                     "grey"
    //                 ]
    //             ]
    //         }
    //     },
    //     {
    //         "id": 371,
    //         "color": {
    //             "label": "black",
    //             "tag": 1324,
    //             "coord": [
    //                 2,
    //                 18,
    //                 32
    //             ],
    //             "ref": [
    //                 [
    //                     "purple",
    //                     "orange",
    //                     "brown"
    //                 ],
    //                 [
    //                     "blue",
    //                     "brown",
    //                     "grey"
    //                 ],
    //                 [
    //                     "purple",
    //                     "blue",
    //                     "blue"
    //                 ]
    //             ]
    //         }
    //     },
    //     {
    //         "id": 590,
    //         "color": {
    //             "label": "red",
    //             "tag": 3340,
    //             "coord": [
    //                 13,
    //                 21,
    //                 13
    //             ],
    //             "ref": [
    //                 [
    //                     "yellow",
    //                     "yellow",
    //                     "red"
    //                 ],
    //                 [
    //                     "blue",
    //                     "brown",
    //                     "grey"
    //                 ],
    //                 [
    //                     "pink",
    //                     "yellow",
    //                     "purple"
    //                 ]
    //             ]
    //         }
    //     }
    // ]
    // 
    
  • 过滤具有[4, 5] 协调器的实体。

    res = client.query(
        collection_name="test_collection",
        data=query_vectors,
        filter='JSON_CONTAINS_ALL(color["coord"], [4, 5])',
        output_fields=["id", "color"],
        limit=3
    )
    
    print(res)
    
    # Output
    #
    # [
    #     {
    #         "id": 281,
    #         "color": {
    #             "label": "red",
    #             "tag": 3645,
    #             "coord": [
    #                 5,
    #                 33,
    #                 4
    #             ],
    #             "ref": [
    #                 [
    #                     "orange",
    #                     "blue",
    #                     "pink"
    #                 ],
    #                 [
    #                     "purple",
    #                     "blue",
    #                     "purple"
    #                 ],
    #                 [
    #                     "black",
    #                     "brown",
    #                     "yellow"
    #                 ]
    #             ]
    #         }
    #     },
    #     {
    #         "id": 464,
    #         "color": {
    #             "label": "brown",
    #             "tag": 6261,
    #             "coord": [
    #                 5,
    #                 9,
    #                 4
    #             ],
    #             "ref": [
    #                 [
    #                     "purple",
    #                     "purple",
    #                     "brown"
    #                 ],
    #                 [
    #                     "black",
    #                     "pink",
    #                     "white"
    #                 ],
    #                 [
    #                     "brown",
    #                     "grey",
    #                     "brown"
    #                 ]
    #             ]
    #         }
    #     },
    #     {
    #         "id": 567,
    #         "color": {
    #             "label": "green",
    #             "tag": 4589,
    #             "coord": [
    #                 5,
    #                 39,
    #                 4
    #             ],
    #             "ref": [
    #                 [
    #                     "purple",
    #                     "yellow",
    #                     "white"
    #                 ],
    #                 [
    #                     "yellow",
    #                     "yellow",
    #                     "brown"
    #                 ],
    #                 [
    #                     "blue",
    #                     "red",
    #                     "yellow"
    #                 ]
    #             ]
    #         }
    #     }
    # ]
    
    searchReq = SearchReq.builder()
        .collectionName("test_collection")
        .data(query_vectors)
        .filter("JSON_CONTAINS_ALL(color[\"coord\"], [4, 5])")
        .outputFields(Arrays.asList("id", "color"))
        .topK(3)
        .build();
    
    searchResp = client.search(searchReq);
    
    System.out.println(JSONObject.toJSON(searchResp));     
    
    // Output:
    // {"searchResults": [[
    //     {
    //         "distance": 0.77485126,
    //         "id": 304,
    //         "entity": {
    //             "color": {
    //                 "coord": [
    //                     4,
    //                     5,
    //                     13
    //                 ],
    //                 "ref": [
    //                     [
    //                         "purple",
    //                         "pink",
    //                         "brown"
    //                     ],
    //                     [
    //                         "orange",
    //                         "red",
    //                         "blue"
    //                     ],
    //                     [
    //                         "yellow",
    //                         "blue",
    //                         "purple"
    //                     ]
    //                 ],
    //                 "label": "blue",
    //                 "tag": 7228
    //             },
    //             "id": 304
    //         }
    //     },
    //     {
    //         "distance": 0.68138736,
    //         "id": 253,
    //         "entity": {
    //             "color": {
    //                 "coord": [
    //                     5,
    //                     38,
    //                     4
    //                 ],
    //                 "ref": [
    //                     [
    //                         "black",
    //                         "pink",
    //                         "blue"
    //                     ],
    //                     [
    //                         "pink",
    //                         "brown",
    //                         "pink"
    //                     ],
    //                     [
    //                         "red",
    //                         "pink",
    //                         "orange"
    //                     ]
    //                 ],
    //                 "label": "blue",
    //                 "tag": 6935
    //             },
    //             "id": 253
    //         }
    //     },
    //     {
    //         "distance": 0.56997097,
    //         "id": 944,
    //         "entity": {
    //             "color": {
    //                 "coord": [
    //                     5,
    //                     6,
    //                     4
    //                 ],
    //                 "ref": [
    //                     [
    //                         "blue",
    //                         "yellow",
    //                         "orange"
    //                     ],
    //                     [
    //                         "orange",
    //                         "white",
    //                         "orange"
    //                     ],
    //                     [
    //                         "pink",
    //                         "brown",
    //                         "white"
    //                     ]
    //                 ],
    //                 "label": "pink",
    //                 "tag": 3325
    //             },
    //             "id": 944
    //         }
    //     }
    // ]]}
    
    res = await client.search({
        collection_name: "test_collection",
        data: query_vectors,
        filter: 'JSON_CONTAINS_ALL(color["coord"], [4, 5])',
        output_fields: ["color", "id"],
        limit: 3
    })
    
    console.log(JSON.stringify(res.results, null, 4))
    
    // Output
    // 
    // [
    //     {
    //         "score": 1.8944344520568848,
    //         "id": "792",
    //         "color": {
    //             "label": "purple",
    //             "tag": 8161,
    //             "coord": [
    //                 4,
    //                 38,
    //                 5
    //             ],
    //             "ref": [
    //                 [
    //                     "red",
    //                     "white",
    //                     "grey"
    //                 ]
    //             ]
    //         }
    //     },
    //     {
    //         "score": 1.2801706790924072,
    //         "id": "489",
    //         "color": {
    //             "label": "red",
    //             "tag": 4358,
    //             "coord": [
    //                 5,
    //                 4,
    //                 1
    //             ],
    //             "ref": [
    //                 [
    //                     "blue",
    //                     "orange",
    //                     "orange"
    //                 ]
    //             ]
    //         }
    //     },
    //     {
    //         "score": 1.2097992897033691,
    //         "id": "656",
    //         "color": {
    //             "label": "red",
    //             "tag": 7856,
    //             "coord": [
    //                 5,
    //                 20,
    //                 4
    //             ],
    //             "ref": [
    //                 [
    //                     "black",
    //                     "orange",
    //                     "white"
    //                 ]
    //             ]
    //         }
    //     }
    // ]
    // 
    
  • 过滤协调器包含45 的实体。

    res = client.query(
        collection_name="test_collection",
        data=query_vectors,
        filter='JSON_CONTAINS_ANY(color["coord"], [4, 5])',
        output_fields=["id", "color"],
        limit=3
    )
    
    print(res)
    
    # Output
    #
    # [
    #     {
    #         "id": 0,
    #         "color": {
    #             "label": "yellow",
    #             "tag": 6340,
    #             "coord": [
    #                 40,
    #                 4,
    #                 40
    #             ],
    #             "ref": [
    #                 [
    #                     "purple",
    #                     "yellow",
    #                     "orange"
    #                 ],
    #                 [
    #                     "green",
    #                     "grey",
    #                     "purple"
    #                 ],
    #                 [
    #                     "black",
    #                     "white",
    #                     "yellow"
    #                 ]
    #             ]
    #         }
    #     },
    #     {
    #         "id": 2,
    #         "color": {
    #             "label": "brown",
    #             "tag": 9359,
    #             "coord": [
    #                 38,
    #                 21,
    #                 5
    #             ],
    #             "ref": [
    #                 [
    #                     "red",
    #                     "brown",
    #                     "white"
    #                 ],
    #                 [
    #                     "purple",
    #                     "red",
    #                     "brown"
    #                 ],
    #                 [
    #                     "pink",
    #                     "grey",
    #                     "black"
    #                 ]
    #             ]
    #         }
    #     },
    #     {
    #         "id": 7,
    #         "color": {
    #             "label": "green",
    #             "tag": 3560,
    #             "coord": [
    #                 5,
    #                 9,
    #                 5
    #             ],
    #             "ref": [
    #                 [
    #                     "blue",
    #                     "orange",
    #                     "green"
    #                 ],
    #                 [
    #                     "blue",
    #                     "blue",
    #                     "black"
    #                 ],
    #                 [
    #                     "green",
    #                     "purple",
    #                     "green"
    #                 ]
    #             ]
    #         }
    #     }
    # ]
    
    searchReq = SearchReq.builder()
        .collectionName("test_collection")
        .data(query_vectors)
        .filter("JSON_CONTAINS_ANY(color[\"coord\"], [4, 5])")
        .outputFields(Arrays.asList("id", "color"))
        .topK(3)
        .build();
    
    searchResp = client.search(searchReq);
    
    System.out.println(JSONObject.toJSON(searchResp));   
    
    // Output:
    // {"searchResults": [[
    //     {
    //         "distance": 1.002122,
    //         "id": 629,
    //         "entity": {
    //             "color": {
    //                 "coord": [
    //                     23,
    //                     5,
    //                     35
    //                 ],
    //                 "ref": [
    //                     [
    //                         "black",
    //                         "yellow",
    //                         "black"
    //                     ],
    //                     [
    //                         "black",
    //                         "purple",
    //                         "white"
    //                     ],
    //                     [
    //                         "black",
    //                         "brown",
    //                         "orange"
    //                     ]
    //                 ],
    //                 "label": "red",
    //                 "tag": 5072
    //             },
    //             "id": 629
    //         }
    //     },
    //     {
    //         "distance": 0.85788506,
    //         "id": 108,
    //         "entity": {
    //             "color": {
    //                 "coord": [
    //                     25,
    //                     5,
    //                     38
    //                 ],
    //                 "ref": [
    //                     [
    //                         "green",
    //                         "brown",
    //                         "pink"
    //                     ],
    //                     [
    //                         "purple",
    //                         "green",
    //                         "green"
    //                     ],
    //                     [
    //                         "green",
    //                         "pink",
    //                         "black"
    //                     ]
    //                 ],
    //                 "label": "orange",
    //                 "tag": 8982
    //             },
    //             "id": 108
    //         }
    //     },
    //     {
    //         "distance": 0.80550396,
    //         "id": 120,
    //         "entity": {
    //             "color": {
    //                 "coord": [
    //                     25,
    //                     16,
    //                     4
    //                 ],
    //                 "ref": [
    //                     [
    //                         "red",
    //                         "green",
    //                         "orange"
    //                     ],
    //                     [
    //                         "blue",
    //                         "pink",
    //                         "blue"
    //                     ],
    //                     [
    //                         "brown",
    //                         "black",
    //                         "green"
    //                     ]
    //                 ],
    //                 "label": "purple",
    //                 "tag": 6711
    //             },
    //             "id": 120
    //         }
    //     }
    // ]]}
    
    res = await client.search({
        collection_name: "test_collection",
        data: query_vectors,
        filter: 'JSON_CONTAINS_ANY(color["coord"], [4, 5])',
        output_fields: ["color", "id"],
        limit: 3
    })
    
    console.log(JSON.stringify(res.results, null, 4))
    
    // Output
    // 
    // [
    //     {
    //         "score": 1.9083369970321655,
    //         "id": "453",
    //         "color": {
    //             "label": "brown",
    //             "tag": 8788,
    //             "coord": [
    //                 21,
    //                 18,
    //                 5
    //             ],
    //             "ref": [
    //                 [
    //                     "pink",
    //                     "black",
    //                     "brown"
    //                 ]
    //             ]
    //         }
    //     },
    //     {
    //         "score": 1.8944344520568848,
    //         "id": "792",
    //         "color": {
    //             "label": "purple",
    //             "tag": 8161,
    //             "coord": [
    //                 4,
    //                 38,
    //                 5
    //             ],
    //             "ref": [
    //                 [
    //                     "red",
    //                     "white",
    //                     "grey"
    //                 ]
    //             ]
    //         }
    //     },
    //     {
    //         "score": 1.8615753650665283,
    //         "id": "272",
    //         "color": {
    //             "label": "grey",
    //             "tag": 3400,
    //             "coord": [
    //                 5,
    //                 1,
    //                 32
    //             ],
    //             "ref": [
    //                 [
    //                     "purple",
    //                     "green",
    //                     "white"
    //                 ]
    //             ]
    //         }
    //     }
    // ]
    // 
    

JSON 过滤器参考

在处理 JSON 字段时,可以将 JSON 字段用作过滤器,也可以使用其中的某些特定键。

注意

  • Milvus 将字符串值原样保存在 JSON 字段中,而不执行语义转义或转换。

例如,'a"b'"a'b"'a\\\\'b'"a\\\\"b" 将按原样保存,而'a'b'"a"b" 将被视为无效值。

  • 要使用 JSON 字段构建过滤表达式,可以利用字段中的键。

  • 如果键值是整数或浮点数,则可以将其与另一个整数或浮点数键值或 INT32/64 或 FLOAT32/64 字段进行比较。

  • 如果键值是字符串,则只能与另一个字符串键或 VARCHAR 字段进行比较。

JSON 字段中的基本操作符

下表假定名为json_key 的 JSON 字段的值有一个名为A 的键。在使用 JSON 字段键构建布尔表达式时,请将其用作参考。

操作符示例备注
<'json_field["A"] < 3'如果json_field["A"] 的值小于3 ,则该表达式的值为 true。
>'json_field["A"] > 1'如果json_field["A"] 的值大于1 ,则此表达式的值为 true。
=='json_field["A"] == 1'如果json_field["A"] 的值等于1 ,则此表达式的值为真。
!='json_field["A"][0]' != "abc"'如果
-json_field 没有名为A 的键,则此表达式的值为真。
-json_field 有一个名为A 的键,但json_field["A"] 不是数组。
-json_field["A"] 是一个空数组。
-json_field["A"] 是一个数组,但第一个元素不是abc
<='json_field["A"] <= 5'如果json_field["A"] 的值小于或等于5 ,则此表达式的值为 true。
>='json_field["A"] >= 1'如果json_field["A"] 的值大于或等于1 ,则此表达式的值为真。
'not json_field["A"] == 1'如果
-json_field 没有名为A 的键,则此表达式的值为真。
-json_field["A"] 不等于1.
'json_field["A"] in [1, 2, 3]'如果json_field["A"] 的值是1,23 ,则此表达式的值为 true。
和 (&&)'json_field["A"] > 1 && json_field["A"] < 3'如果json_field["A"] 的值大于 1 且小于3 ,则此表达式的值为 true。
或 (||)‘json_field[“A”] > 1 || json_field[“A”] < 3’如果json_field["A"] 的值大于1 或小于3 ,则此表达式的值为 true。
存在'exists json_field["A"]'如果json_field 有一个名为A 的键,则此表达式的值为真。

高级操作符

以下操作符专门针对 JSON 字段:

  • json_contains(identifier, jsonExpr)

    此操作符可过滤标识符包含指定 JSON 表达式的实体。

    • 例 1:{"x": [1,2,3]}

      json_contains(x, 1) # => True (x contains 1.)
      json_contains(x, "a") # => False (x does not contain a member "a".)
      
    • 例 2:{"x", [[1,2,3], [4,5,6], [7,8,9]]}

      json_contains(x, [1,2,3]) # => True (x contains [1,2,3].)
      json_contains(x, [3,2,1]) # => False (x does contain a member [3,2,1].)
      
  • json_contains_all(identifier, jsonExpr)

    该操作符可过滤标识符包含 JSON 表达式所有成员的实体。

    示例{"x": [1,2,3,4,5,7,8]}

    json_contains_all(x, [1,2,8]) # => True (x contains 1, 2, and 8.)
    json_contains_all(x, [4,5,6]) # => False (x does not has a member 6.)
    
  • json_contains_any(identifier, jsonExpr)

    此操作符可过滤标识符包含 JSON 表达式中任何成员的实体。

    示例{"x": [1,2,3,4,5,7,8]}

    json_contains_any(x, [1,2,8]) # => True (x contains 1, 2, and 8.)
    json_contains_any(x, [4,5,6]) # => True (x contains 4 and 5.)
    json_contains_any(x, [6,9]) # => False (x contains none of 6 and 9.)
    

翻译自DeepLogo

反馈

此页对您是否有帮助?