Utiliser les champs JSON
Ce guide explique comment utiliser les champs JSON, notamment en insérant des valeurs JSON et en effectuant des recherches et des requêtes dans les champs JSON à l'aide d'opérateurs de base et avancés.
Vue d'ensemble
JSON est l'abréviation de Javascript Object Notation, un format de données textuelles simple et léger. Les données JSON sont structurées en paires clé-valeur, où chaque clé est une chaîne qui correspond à une valeur de type nombre, chaîne, booléen, liste ou tableau. Avec les clusters Milvus, il est possible de stocker des dictionnaires en tant que valeur de champ dans des collections.
Par exemple, le code suivant génère aléatoirement des paires clé-valeur, chacune contenant un champ JSON avec la clé couleur.
# 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.*;
import com.google.gson.Gson;
import com.google.gson.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<>();
Gson gson = new Gson();
Random rand = new Random();
for (int i=0; i<1000; i++) {
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.addProperty("id", (long) i);
row.add("vector", gson.toJsonTree(Arrays.asList(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat())));
JsonObject color = new JsonObject();
color.addProperty("label", current_color);
color.addProperty("tag", current_tag);
color.add("coord", gson.toJsonTree(current_coord));
color.add("ref", gson.toJsonTree(current_ref));
row.add("color", color);
data.add(row);
}
System.out.println(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])
Vous pouvez visualiser la structure des données générées en vérifiant la première entrée.
{
"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"
]
]
}
}
notes
Assurez-vous que toutes les valeurs d'une liste ou d'un tableau sont du même type de données.
Tout dictionnaire imbriqué dans une valeur de champ JSON sera considéré comme une chaîne de caractères.
N'utilisez que des caractères alphanumériques et des traits de soulignement pour nommer les clés JSON, car d'autres caractères peuvent poser des problèmes de filtrage ou de recherche.
- Actuellement, l'indexation des champs JSON n'est pas disponible, ce qui peut rendre le filtrage fastidieux. Cette limitation sera toutefois prise en compte dans les prochaines versions.
Définir un champ JSON
Pour définir un champ JSON, il suffit de suivre la même procédure que pour les autres types de champs.
Pour plus d'informations sur les paramètres, voir MilvusClient
, create_schema()
, add_field()
, add_index()
, create_collection()
, et get_load_state()
dans la référence du SDK.
Pour plus d'informations sur les paramètres, voir MilvusClientV2
, createSchema()
, addField()
, IndexParam
, createCollection()
, et getLoadState()
dans la référence du SDK.
Pour plus d'informations sur les paramètres, voir MilvusClient
et createCollection()
et createCollection()
dans la référence du SDK.
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>"
# }
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.common.DataType;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.*;
import io.milvus.v2.service.vector.request.*;
import io.milvus.v2.service.vector.request.data.*;
import io.milvus.v2.service.vector.response.*;
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();
Map<String, Object> params = new HashMap<>();
params.put("nlist", 1024);
IndexParam indexParamForVectorField = IndexParam.builder()
.fieldName("vector")
.indexType(IndexParam.IndexType.IVF_FLAT)
.metricType(IndexParam.MetricType.IP)
.extraParams(params)
.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
//
Pour plus d'informations sur les paramètres, voir MilvusClient
, create_schema()
, add_field()
, add_index()
, create_collection()
, et get_load_state()
dans la référence du SDK.
Pour plus d'informations sur les paramètres, voir MilvusClientV2
, createSchema()
, addField()
, IndexParam
, createCollection()
, et getLoadState()
dans la référence du SDK.
Pour plus d'informations sur les paramètres, voir MilvusClient
, createCollection()
, et getLoadState()
dans la référence du SDK.
Insérer des valeurs de champ
Après avoir créé une collection à partir de l'objet CollectionSchema
, il est possible d'y insérer des dictionnaires tels que celui présenté ci-dessus.
Utilisez la méthode insert()
pour insérer les données dans la collection.
Utilisez la méthode insert()
pour insérer les données dans la collection.
Utilisez la méthode insert()
pour insérer les données dans la collection.
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(insertResp.getInsertCnt());
// Output:
// 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
//
Filtrage scalaire de base
Une fois que toutes les données ont été ajoutées, vous pouvez effectuer des recherches et des requêtes en utilisant les clés du champ JSON de la même manière que vous le feriez avec un champ scalaire standard.
Pour plus d'informations sur les paramètres, reportez-vous à search()
dans la référence SDK.
Pour plus d'informations sur les paramètres, voir search()
dans la référence du SDK.
Pour plus d'informations sur les paramètres, voir search()
dans la référence du 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. Search with partition key
List<BaseVector> query_vectors = Collections.singletonList(new FloatVec(new float[]{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);
List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
System.out.println("TopK results:");
for (SearchResp.SearchResult result : results) {
System.out.println(result);
}
}
// Output:
// SearchResp.SearchResult(entity=\{color=\{"label":"red","tag":1018,"coord":[3,30,1],"ref":[["yellow","brown","orange"],["yellow","purple","blue"],["green","purple","purple"]]}, id=295}, score=1.1190735, id=295)
// SearchResp.SearchResult(entity=\{color=\{"label":"red","tag":8141,"coord":[38,31,29],"ref":[["blue","white","white"],["green","orange","green"],["yellow","green","black"]]}, id=667}, score=1.0679582, id=667)
// SearchResp.SearchResult(entity=\{color=\{"label":"red","tag":6837,"coord":[29,9,8],"ref":[["green","black","blue"],["purple","white","green"],["red","blue","black"]]}, id=927}, score=1.0029297, id=927)
// 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"]
// ]
// }
// }
// ]
//
Filtrage scalaire avancé
Milvus fournit un ensemble de filtres avancés pour le filtrage scalaire dans les champs JSON. Ces filtres sont JSON_CONTAINS
, JSON_CONTAINS_ALL
, et JSON_CONTAINS_ANY
.
Filtre toutes les entités dont le jeu de couleurs de référence est
["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); searchResults = searchResp.getSearchResults(); for (List<SearchResp.SearchResult> results : searchResults) { System.out.println("TopK results:"); for (SearchResp.SearchResult result : results) { System.out.println(result); } } // Output: // SearchResp.SearchResult(entity={color={"label":"pink","tag":2963,"coord":[15,33,30],"ref":[["green","white","white"],["purple","pink","orange"],["yellow","black","pink"]]}, id=273}, score=0.46558747, id=273) // SearchResp.SearchResult(entity={color={"label":"pink","tag":4027,"coord":[32,34,19],"ref":[["red","white","blue"],["white","pink","yellow"],["purple","pink","orange"]]}, id=344}, score=0.2637315, id=344) // SearchResp.SearchResult(entity={color={"label":"black","tag":1603,"coord":[33,12,23],"ref":[["pink","brown","black"],["black","purple","black"],["purple","pink","orange"]]}, id=205}, score=0.26133868, id=205)
// 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" // ] // ] // } // } // ] //
Filtre les entités dont le coordinateur est
[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); searchResults = searchResp.getSearchResults(); for (List<SearchResp.SearchResult> results : searchResults) { System.out.println("TopK results:"); for (SearchResp.SearchResult result : results) { System.out.println(result); } } // Output: // SearchResp.SearchResult(entity={color={"label":"green","tag":9899,"coord":[5,4,25],"ref":[["purple","black","yellow"],["orange","green","purple"],["red","purple","pink"]]}, id=708}, score=0.56576324, id=708) // SearchResp.SearchResult(entity={color={"label":"red","tag":2176,"coord":[4,5,23],"ref":[["red","black","green"],["brown","orange","brown"],["brown","orange","yellow"]]}, id=981}, score=0.5656834, id=981) // SearchResp.SearchResult(entity={color={"label":"pink","tag":3085,"coord":[5,3,4],"ref":[["yellow","orange","green"],["black","pink","red"],["orange","blue","blue"]]}, id=221}, score=0.3708634, id=221)
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" // ] // ] // } // } // ] //
Filtre les entités dont le coordinateur contient
4
ou5
.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); searchResults = searchResp.getSearchResults(); for (List<SearchResp.SearchResult> results : searchResults) { System.out.println("TopK results:"); for (SearchResp.SearchResult result : results) { System.out.println(result); } } // Output: // SearchResp.SearchResult(entity={color={"label":"brown","tag":8414,"coord":[3,4,15],"ref":[["blue","green","pink"],["red","orange","pink"],["yellow","pink","green"]]}, id=11}, score=1.18235, id=11) // SearchResp.SearchResult(entity={color={"label":"yellow","tag":2846,"coord":[20,4,15],"ref":[["white","black","purple"],["green","black","yellow"],["red","purple","brown"]]}, id=589}, score=1.1414992, id=589) // SearchResp.SearchResult(entity={color={"label":"pink","tag":6744,"coord":[25,33,5],"ref":[["orange","purple","white"],["white","pink","brown"],["red","pink","red"]]}, id=567}, score=1.1087029, id=567)
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" // ] // ] // } // } // ] //
Référence sur les filtres JSON
Lorsque vous travaillez avec des champs JSON, vous pouvez utiliser les champs JSON comme filtres ou certaines de leurs clés spécifiques.
notes
- Milvus stocke les valeurs de chaîne dans le champ JSON telles quelles sans effectuer d'échappement sémantique ou de conversion.
Par exemple, 'a"b'
, "a'b"
, 'a\\\\'b'
, et "a\\\\"b"
seront enregistrés tels quels, tandis que 'a'b'
et "a"b"
seront traités comme des valeurs non valides.
Pour construire des expressions de filtre à l'aide d'un champ JSON, vous pouvez utiliser les clés du champ.
Si la valeur d'une clé est un entier ou un flottant, vous pouvez la comparer à une autre clé d'entier ou de flottant ou à un champ INT32/64 ou FLOAT32/64.
Si la valeur d'une clé est une chaîne de caractères, vous ne pouvez la comparer qu'avec une autre clé de type chaîne de caractères ou un champ VARCHAR.
Opérateurs de base dans les champs JSON
Le tableau suivant suppose que la valeur d'un champ JSON nommé json_key
a une clé nommée A
. Utilisez-le comme référence lors de la construction d'expressions booléennes utilisant des clés de champ JSON.
Opérateur | Exemples | Remarques |
---|---|---|
< | 'json_field["A"] < 3' | Cette expression est vraie si la valeur de json_field["A"] est inférieure à 3 . |
> | 'json_field["A"] > 1' | Cette expression est vraie si la valeur de json_field["A"] est supérieure à 1 . |
== | 'json_field["A"] == 1' | Cette expression est considérée comme vraie si la valeur de json_field["A"] est égale à 1 . |
!= | 'json_field["A"][0]' != "abc"' | Cette expression est considérée comme vraie si - json_field n'a pas de clé nommée A .- json_field a une clé nommée A mais json_field["A"] n'est pas un tableau.- json_field["A"] est un tableau vide.- json_field["A"] est un tableau mais le premier élément n'est pas abc . |
<= | 'json_field["A"] <= 5' | Cette expression est vraie si la valeur de json_field["A"] est inférieure ou égale à 5 . |
>= | 'json_field["A"] >= 1' | Cette expression est considérée comme vraie si la valeur de json_field["A"] est supérieure ou égale à 1 . |
not | 'not json_field["A"] == 1' | Cette expression est considérée comme vraie si - json_field n'a pas de clé nommée A .- json_field["A"] n'est pas égal à 1 . |
in | 'json_field["A"] in [1, 2, 3]' | Cette expression est considérée comme vraie si la valeur de json_field["A"] est 1 , 2 , ou 3 . |
et (&&) | 'json_field["A"] > 1 && json_field["A"] < 3' | Cette expression est vraie si la valeur de json_field["A"] est supérieure à 1 et inférieure à 3 . |
ou (||) | ‘json_field[“A”] > 1 || json_field[“A”] < 3’ | Cette expression est considérée comme vraie si la valeur de json_field["A"] est supérieure à 1 ou inférieure à 3 . |
existe | 'exists json_field["A"]' | Cette expression est considérée comme vraie si json_field possède une clé nommée A . |
Opérateurs avancés
Les opérateurs suivants sont spécifiques aux champs JSON :
json_contains(identifier, jsonExpr)
Cet opérateur filtre les entités dont l'identifiant contient l'expression JSON spécifiée.
Exemple 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".)
Exemple 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)
Cet opérateur filtre les entités dont l'identifiant contient tous les membres de l'expression JSON.
Exemple :
{"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)
Cet opérateur filtre les entités dont l'identifiant contient tous les membres de l'expression JSON.
Exemple : Cet opérateur filtre les entités dont l'identifiant contient tous les membres de l'expression 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.)