milvus-logo
LFAI
Home
  • Guide de l'utilisateur

Recherche à vecteur unique

Une fois que vous avez inséré vos données, l'étape suivante consiste à effectuer des recherches de similarité sur votre collection dans Milvus.

Milvus vous permet d'effectuer deux types de recherche, en fonction du nombre de champs vectoriels de votre collection :

  • Recherche sur un seul champ vectoriel: Si votre collection ne comporte qu'un seul champ vectoriel, utilisez la méthode search() pour trouver les entités les plus similaires. Cette méthode compare le vecteur de votre requête avec les vecteurs existants dans votre collection et renvoie les ID des entités les plus proches ainsi que les distances qui les séparent. En option, elle peut également renvoyer les valeurs des vecteurs et les métadonnées des résultats.
  • Recherche hybride: Pour les collections comportant deux champs vectoriels ou plus, utilisez la méthode hybrid_search() pour les collections comportant deux champs vectoriels ou plus. Cette méthode exécute plusieurs requêtes de recherche ANN (Approximate Nearest Neighbor) et combine les résultats pour renvoyer les correspondances les plus pertinentes après reclassement.

Ce guide explique comment effectuer une recherche sur un seul vecteur dans Milvus. Pour plus de détails sur la recherche hybride, reportez-vous à la section Recherche hybride.

Vue d'ensemble

Il existe plusieurs types de recherche pour répondre à différents besoins :

  • Recherche de base: Comprend la recherche sur un seul vecteur, la recherche sur un grand nombre de vecteurs, la recherche sur une partition et la recherche avec des champs de sortie spécifiés.

  • Recherche filtrée: Elle applique des critères de filtrage basés sur des champs scalaires pour affiner les résultats de la recherche.

  • Recherche par plage: Permet de trouver des vecteurs situés dans une plage de distance spécifique par rapport au vecteur de la requête.

  • Recherche groupée: Regroupe les résultats de la recherche sur la base d'un champ spécifique afin de garantir la diversité des résultats.

Préparations

L'extrait de code ci-dessous reprend le code existant pour établir une connexion avec Milvus et configurer rapidement une collection.

from pymilvus import MilvusClient
import random

# 1. Set up a Milvus client
client = MilvusClient(
    uri="http://localhost:19530"
)

# 2. Create a collection
client.create_collection(
    collection_name="quick_setup",
    dimension=5,
    metric_type="IP"
)

# 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)
    data.append({
        "id": i,
        "vector": [ random.uniform(-1, 1) for _ in range(5) ],
        "color": current_color,
        "color_tag": f"{current_color}_{str(random.randint(1000, 9999))}"
    })

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

print(res)

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

# 6.1 Create partitions 
client.create_partition(
    collection_name="quick_setup",
    partition_name="red"
)

client.create_partition(
    collection_name="quick_setup",
    partition_name="blue"
)

# 6.1 Insert data into partitions
red_data = [ {"id": i, "vector": [ random.uniform(-1, 1) for _ in range(5) ], "color": "red", "color_tag": f"red_{str(random.randint(1000, 9999))}" } for i in range(500) ]
blue_data = [ {"id": i, "vector": [ random.uniform(-1, 1) for _ in range(5) ], "color": "blue", "color_tag": f"blue_{str(random.randint(1000, 9999))}" } for i in range(500) ]

res = client.insert(
    collection_name="quick_setup",
    data=red_data,
    partition_name="red"
)

print(res)

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

res = client.insert(
    collection_name="quick_setup",
    data=blue_data,
    partition_name="blue"
)

print(res)

# Output
#
# {
#     "insert_count": 500,
#     "ids": [
#         0,
#         1,
#         2,
#         3,
#         4,
#         5,
#         6,
#         7,
#         8,
#         9,
#         "(490 more items hidden)"
#     ]
# }
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;

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
import io.milvus.v2.service.collection.request.GetLoadStateReq;
import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.response.InsertResp; 

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 quick setup mode
CreateCollectionReq quickSetupReq = CreateCollectionReq.builder()
    .collectionName("quick_setup")
    .dimension(5)
    .metricType("IP")
    .build();

client.createCollection(quickSetupReq);

GetLoadStateReq loadStateReq = GetLoadStateReq.builder()
    .collectionName("quick_setup")
    .build();

boolean state = client.getLoadState(loadStateReq);

System.out.println(state);

// Output:
// true

// 3. Insert randomly generated vectors 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));
    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()));
    row.put("color_tag", current_color + "_" + String.valueOf(rand.nextInt(8999) + 1000));
    data.add(row);
}

InsertReq insertReq = InsertReq.builder()
    .collectionName("quick_setup")
    .data(data)
    .build();

InsertResp insertResp = client.insert(insertReq);

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

// Output:
// {"insertCnt": 1000}

// 6.1. Create a partition
CreatePartitionReq partitionReq = CreatePartitionReq.builder()
    .collectionName("quick_setup")
    .partitionName("red")
    .build();

client.createPartition(partitionReq);

partitionReq = CreatePartitionReq.builder()
    .collectionName("quick_setup")
    .partitionName("blue")
    .build();

client.createPartition(partitionReq);

// 6.2 Insert data into the partition
data = new ArrayList<>();

for (int i=1000; i<1500; i++) {
    Random rand = new Random();
    String current_color = "red";
    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()));
    row.put("color", current_color);
    row.put("color_tag", current_color + "_" + String.valueOf(rand.nextInt(8999) + 1000));
    data.add(row);
}     

insertReq = InsertReq.builder()
    .collectionName("quick_setup")
    .data(data)
    .partitionName("red")
    .build();

insertResp = client.insert(insertReq);

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

// Output:
// {"insertCnt": 500}

data = new ArrayList<>();

for (int i=1500; i<2000; i++) {
    Random rand = new Random();
    String current_color = "blue";
    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()));
    row.put("color", current_color);
    row.put("color_tag", current_color + "_" + String.valueOf(rand.nextInt(8999) + 1000));
    data.add(row);
}

insertReq = InsertReq.builder()
    .collectionName("quick_setup")
    .data(data)
    .partitionName("blue")
    .build();

insertResp = client.insert(insertReq);

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

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

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

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

// 2. Create a collection in quick setup mode
await client.createCollection({
    collection_name: "quick_setup",
    dimension: 5,
    metric_type: "IP"
});  

// 3. Insert randomly generated vectors
const colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"]
data = []

for (let i = 0; i < 1000; i++) {
    current_color = colors[Math.floor(Math.random() * colors.length)]
    data.push({
        id: i,
        vector: [Math.random(), Math.random(), Math.random(), Math.random(), Math.random()],
        color: current_color,
        color_tag: `${current_color}_${Math.floor(Math.random() * 8999) + 1000}`
    })
}

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

console.log(res.insert_cnt)

// Output
// 
// 1000
// 

await client.createPartition({
    collection_name: "quick_setup",
    partition_name: "red"
})

await client.createPartition({
    collection_name: "quick_setup",
    partition_name: "blue"
})

// 6.1 Insert data into partitions
var red_data = []
var blue_data = []

for (let i = 1000; i < 1500; i++) {
    red_data.push({
        id: i,
        vector: [Math.random(), Math.random(), Math.random(), Math.random(), Math.random()],
        color: "red",
        color_tag: `red_${Math.floor(Math.random() * 8999) + 1000}`
    })
}

for (let i = 1500; i < 2000; i++) {
    blue_data.push({
        id: i,
        vector: [Math.random(), Math.random(), Math.random(), Math.random(), Math.random()],
        color: "blue",
        color_tag: `blue_${Math.floor(Math.random() * 8999) + 1000}`
    })
}

res = await client.insert({
    collection_name: "quick_setup",
    data: red_data,
    partition_name: "red"
})

console.log(res.insert_cnt)

// Output
// 
// 500
// 

res = await client.insert({
    collection_name: "quick_setup",
    data: blue_data,
    partition_name: "blue"
})

console.log(res.insert_cnt)

// Output
// 
// 500
// 

Lors de l'envoi d'une requête search, vous pouvez fournir une ou plusieurs valeurs vectorielles représentant vos enchâssements de requête et une valeur limit indiquant le nombre de résultats à renvoyer.

En fonction de vos données et de votre vecteur d'interrogation, il se peut que vous obteniez moins de limit résultats. Cela se produit lorsque limit est plus grand que le nombre de vecteurs correspondant à votre requête.

La recherche à vecteur unique est la forme la plus simple des opérations search dans Milvus, conçue pour trouver les vecteurs les plus similaires à un vecteur d'interrogation donné.

Pour effectuer une recherche à vecteur unique, indiquez le nom de la collection cible, le vecteur d'interrogation et le nombre de résultats souhaité (limit). Cette opération renvoie un ensemble de résultats comprenant les vecteurs les plus similaires, leurs identifiants et les distances par rapport au vecteur d'interrogation.

Voici un exemple de recherche des 5 entités les plus similaires au vecteur d'interrogation :

# Single vector search
res = client.search(
    collection_name="quick_setup", # Replace with the actual name of your collection
    # Replace with your query vector
    data=[[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]],
    limit=5, # Max. number of search results to return
    search_params={"metric_type": "IP", "params": {}} # Search parameters
)

# Convert the output to a formatted JSON string
result = json.dumps(res, indent=4)
print(result)
// 4. Single vector search
List<List<Float>> query_vectors = Arrays.asList(Arrays.asList(0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f));

SearchReq searchReq = SearchReq.builder()
    .collectionName("quick_setup")
    .data(query_vectors)
    .topK(3) // The number of results to return
    .build();

SearchResp searchResp = client.search(searchReq);

System.out.println(JSONObject.toJSON(searchResp));
// 4. Single vector search
var query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],

res = await client.search({
    collection_name: "quick_setup",
    data: [query_vector],
    limit: 3, // The number of results to return
})

console.log(res.results)
Paramètres Description de la collection
collection_name Le nom d'une collection existante.
data Une liste d'intégrations vectorielles.
Milvus recherche les intégrations vectorielles les plus similaires à celles spécifiées.
limit Le nombre total d'entités à renvoyer.
Vous pouvez utiliser ce paramètre en combinaison avec offset in param pour activer la pagination.
La somme de cette valeur et de offset in param doit être inférieure à 16 384.
search_params Les paramètres spécifiques à cette opération.
  • metric_type: Le type de métrique appliqué à cette opération. Il doit être le même que celui utilisé lors de l'indexation du champ vectoriel spécifié ci-dessus. Les valeurs possibles sont L2, IP, COSINE, JACCARD, HAMMING.
  • params: Paramètres supplémentaires. Pour plus de détails, voir search().
Paramètre Description de la collection
collectionName Le nom d'une collection existante.
data Une liste d'intégrations vectorielles.
Milvus recherche les intégrations vectorielles les plus similaires à celles spécifiées.
topK Le nombre d'enregistrements à renvoyer dans le résultat de la recherche. Ce paramètre utilise la même syntaxe que le paramètre limit, vous ne devez donc en définir qu'un seul.
Vous pouvez utiliser ce paramètre en combinaison avec offset in param pour activer la pagination.
La somme de cette valeur et de offset in param doit être inférieure à 16 384.
Paramètre Description
collection_name Le nom d'une collection existante.
data Une liste d'intégrations vectorielles.
Milvus recherche les intégrations vectorielles les plus similaires à celles spécifiées.
limit Le nombre total d'entités à renvoyer.
Vous pouvez utiliser ce paramètre en combinaison avec offset dans param pour activer la pagination.
La somme de cette valeur et de offset dans param doit être inférieure à 16 384.

La sortie est similaire à ce qui suit :

[
    [
        {
            "id": 0,
            "distance": 1.4093276262283325,
            "entity": {}
        },
        {
            "id": 4,
            "distance": 0.9902134537696838,
            "entity": {}
        },
        {
            "id": 1,
            "distance": 0.8519943356513977,
            "entity": {}
        },
        {
            "id": 5,
            "distance": 0.7972343564033508,
            "entity": {}
        },
        {
            "id": 2,
            "distance": 0.5928734540939331,
            "entity": {}
        }
    ]
]
{"searchResults": [[
    {
        "score": 1.263043,
        "fields": {
            "vector": [
                0.9533119,
                0.02538395,
                0.76714665,
                0.35481733,
                0.9845762
            ],
            "id": 740
        }
    },
    {
        "score": 1.2377806,
        "fields": {
            "vector": [
                0.7411156,
                0.08687937,
                0.8254139,
                0.08370924,
                0.99095553
            ],
            "id": 640
        }
    },
    {
        "score": 1.1869997,
        "fields": {
            "vector": [
                0.87928146,
                0.05324632,
                0.6312755,
                0.28005534,
                0.9542448
            ],
            "id": 455
        }
    }
]]}
[
  { score: 1.7463608980178833, id: '854' },
  { score: 1.744946002960205, id: '425' },
  { score: 1.7258622646331787, id: '718' }
]

Le résultat présente les 5 voisins les plus proches de votre vecteur d'interrogation, y compris leurs identifiants uniques et les distances calculées.

La recherche de vecteurs en vrac étend le concept de recherche à vecteur unique en permettant de rechercher plusieurs vecteurs d'interrogation en une seule requête. Ce type de recherche est idéal pour les scénarios dans lesquels vous devez trouver des vecteurs similaires pour un ensemble de vecteurs d'interrogation, ce qui réduit considérablement le temps et les ressources informatiques nécessaires.

Dans une recherche de vecteurs en vrac, vous pouvez inclure plusieurs vecteurs d'interrogation dans le champ data. Le système traite ces vecteurs en parallèle et renvoie un ensemble de résultats distinct pour chaque vecteur d'interrogation, chaque ensemble contenant les correspondances les plus proches trouvées dans la collection.

Voici un exemple de recherche de deux ensembles distincts d'entités les plus similaires à partir de deux vecteurs d'interrogation :

# Bulk-vector search
res = client.search(
    collection_name="quick_setup", # Replace with the actual name of your collection
    data=[
        [0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104],
        [0.3172005263489739, 0.9719044792798428, -0.36981146090600725, -0.4860894583077995, 0.95791889146345]
    ], # Replace with your query vectors
    limit=2, # Max. number of search results to return
    search_params={"metric_type": "IP", "params": {}} # Search parameters
)

result = json.dumps(res, indent=4)
print(result)
// 5. Batch vector search
query_vectors = Arrays.asList(
    Arrays.asList(0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f),
    Arrays.asList(0.19886812562848388f, 0.06023560599112088f, 0.6976963061752597f, 0.2614474506242501f, 0.838729485096104f)
);

searchReq = SearchReq.builder()
    .collectionName("quick_setup")
    .data(query_vectors)
    .topK(2)
    .build();

searchResp = client.search(searchReq);

System.out.println(JSONObject.toJSON(searchResp));
// 5. Batch vector search
var query_vectors = [
    [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
    [0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104]
]

res = await client.search({
    collection_name: "quick_setup",
    data: query_vectors,
    limit: 2,
})

console.log(res.results)

La sortie est similaire à ce qui suit :

[
    [
        {
            "id": 1,
            "distance": 1.3017789125442505,
            "entity": {}
        },
        {
            "id": 7,
            "distance": 1.2419954538345337,
            "entity": {}
        }
    ], # Result set 1
    [
        {
            "id": 3,
            "distance": 2.3358664512634277,
            "entity": {}
        },
        {
            "id": 8,
            "distance": 0.5642921924591064,
            "entity": {}
        }
    ] # Result set 2
]
// Two sets of vectors are returned as expected

{"searchResults": [
    [
        {
            "score": 1.263043,
            "fields": {
                "vector": [
                    0.9533119,
                    0.02538395,
                    0.76714665,
                    0.35481733,
                    0.9845762
                ],
                "id": 740
            }
        },
        {
            "score": 1.2377806,
            "fields": {
                "vector": [
                    0.7411156,
                    0.08687937,
                    0.8254139,
                    0.08370924,
                    0.99095553
                ],
                "id": 640
            }
        }
    ],
    [
        {
            "score": 1.8654699,
            "fields": {
                "vector": [
                    0.4671427,
                    0.8378432,
                    0.98844475,
                    0.82763994,
                    0.9729997
                ],
                "id": 638
            }
        },
        {
            "score": 1.8581753,
            "fields": {
                "vector": [
                    0.735541,
                    0.60140246,
                    0.86730254,
                    0.93152493,
                    0.98603314
                ],
                "id": 855
            }
        }
    ]
]}
[
  [
    { score: 2.3590476512908936, id: '854' },
    { score: 2.2896690368652344, id: '59' }
  [
    { score: 2.664059638977051, id: '59' },
    { score: 2.59483003616333, id: '854' }
  ]
]

Les résultats comprennent deux ensembles de plus proches voisins, un pour chaque vecteur d'interrogation, ce qui montre l'efficacité des recherches de vecteurs en vrac dans le traitement de plusieurs vecteurs d'interrogation à la fois.

La recherche par partition réduit la portée de votre recherche à un sous-ensemble ou à une partition spécifique de votre collection. Elle est particulièrement utile pour les ensembles de données organisés où les données sont segmentées en divisions logiques ou catégorielles, ce qui permet d'accélérer les opérations de recherche en réduisant le volume de données à analyser.

Pour effectuer une recherche par partition, il suffit d'inclure le nom de la partition cible dans partition_names de votre demande de recherche. Cela indique que l'opération search ne prend en compte que les vecteurs situés dans la partition spécifiée.

Voici un exemple de recherche d'entités dans red:

# 6.2 Search within a partition
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]

res = client.search(
    collection_name="quick_setup",
    data=[query_vector],
    limit=5,
    search_params={"metric_type": "IP", "params": {"level": 1}},
    partition_names=["red"]
)

print(res)
// 6.3 Search within partitions
query_vectors = Arrays.asList(Arrays.asList(0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f));

searchReq = SearchReq.builder()
    .collectionName("quick_setup")
    .data(query_vectors)
    .partitionNames(Arrays.asList("red"))
    .topK(5)
    .build();

searchResp = client.search(searchReq);

System.out.println(JSONObject.toJSON(searchResp));
// 6.2 Search within partitions
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]

res = await client.search({
    collection_name: "quick_setup",
    data: [query_vector],
    partition_names: ["red"],
    limit: 5,
})

console.log(res.results)

La sortie est similaire à ce qui suit :

[
    [
        {
            "id": 16,
            "distance": 0.9200337529182434,
            "entity": {}
        },
        {
            "id": 14,
            "distance": 0.4505271911621094,
            "entity": {}
        },
        {
            "id": 15,
            "distance": 0.19924677908420563,
            "entity": {}
        },
        {
            "id": 17,
            "distance": 0.0075093843042850494,
            "entity": {}
        },
        {
            "id": 13,
            "distance": -0.14609718322753906,
            "entity": {}
        }
    ]
]
{"searchResults": [
    [
        {
            "score": 1.1677284,
            "fields": {
                "vector": [
                    0.9986977,
                    0.17964739,
                    0.49086612,
                    0.23155272,
                    0.98438674
                ],
                "id": 1435
            }
        },
        {
            "score": 1.1476475,
            "fields": {
                "vector": [
                    0.6952647,
                    0.13417172,
                    0.91045254,
                    0.119336545,
                    0.9338931
                ],
                "id": 1291
            }
        },
        {
            "score": 1.0969629,
            "fields": {
                "vector": [
                    0.3363194,
                    0.028906643,
                    0.6675426,
                    0.030419827,
                    0.9735209
                ],
                "id": 1168
            }
        },
        {
            "score": 1.0741848,
            "fields": {
                "vector": [
                    0.9980543,
                    0.36063594,
                    0.66427994,
                    0.17359233,
                    0.94954175
                ],
                "id": 1164
            }
        },
        {
            "score": 1.0584627,
            "fields": {
                "vector": [
                    0.7187005,
                    0.12674773,
                    0.987718,
                    0.3110777,
                    0.86093885
                ],
                "id": 1085
            }
        }
    ],
    [
        {
            "score": 1.8030131,
            "fields": {
                "vector": [
                    0.59726167,
                    0.7054632,
                    0.9573117,
                    0.94529945,
                    0.8664103
                ],
                "id": 1203
            }
        },
        {
            "score": 1.7728865,
            "fields": {
                "vector": [
                    0.6672442,
                    0.60448086,
                    0.9325822,
                    0.80272985,
                    0.8861626
                ],
                "id": 1448
            }
        },
        {
            "score": 1.7536311,
            "fields": {
                "vector": [
                    0.59663296,
                    0.77831805,
                    0.8578314,
                    0.88818026,
                    0.9030075
                ],
                "id": 1010
            }
        },
        {
            "score": 1.7520742,
            "fields": {
                "vector": [
                    0.854198,
                    0.72294194,
                    0.9245805,
                    0.86126596,
                    0.7969224
                ],
                "id": 1219
            }
        },
        {
            "score": 1.7452049,
            "fields": {
                "vector": [
                    0.96419,
                    0.943535,
                    0.87611496,
                    0.8268136,
                    0.79786557
                ],
                "id": 1149
            }
        }
    ]
]}
[
  { score: 3.0258803367614746, id: '1201' },
  { score: 3.004319190979004, id: '1458' },
  { score: 2.880324363708496, id: '1187' },
  { score: 2.8246407508850098, id: '1347' },
  { score: 2.797295093536377, id: '1406' }
]

Ensuite, recherchez des entités dans blue:

res = client.search(
    collection_name="quick_setup",
    data=[query_vector],
    limit=5,
    search_params={"metric_type": "IP", "params": {"level": 1}},
    partition_names=["blue"]
)

print(res)
searchReq = SearchReq.builder()
    .collectionName("quick_setup")
    .data(query_vectors)
    .partitionNames(Arrays.asList("blue"))
    .topK(5)
    .build();

searchResp = client.search(searchReq);

System.out.println(JSONObject.toJSON(searchResp));
res = await client.search({
    collection_name: "quick_setup",
    data: [query_vector],
    partition_names: ["blue"],
    limit: 5,
})

console.log(res.results)

La sortie est similaire à ce qui suit :

[
    [
        {
            "id": 20,
            "distance": 2.363696813583374,
            "entity": {}
        },
        {
            "id": 26,
            "distance": 1.0665391683578491,
            "entity": {}
        },
        {
            "id": 23,
            "distance": 1.066049575805664,
            "entity": {}
        },
        {
            "id": 29,
            "distance": 0.8353596925735474,
            "entity": {}
        },
        {
            "id": 28,
            "distance": 0.7484277486801147,
            "entity": {}
        }
    ]
]
{"searchResults": [
    [
        {
            "score": 1.1628494,
            "fields": {
                "vector": [
                    0.7442872,
                    0.046407282,
                    0.71031404,
                    0.3544345,
                    0.9819991
                ],
                "id": 1992
            }
        },
        {
            "score": 1.1470042,
            "fields": {
                "vector": [
                    0.5505825,
                    0.04367262,
                    0.9985836,
                    0.18922359,
                    0.93255126
                ],
                "id": 1977
            }
        },
        {
            "score": 1.1450152,
            "fields": {
                "vector": [
                    0.89994013,
                    0.052991092,
                    0.8645576,
                    0.6406729,
                    0.95679337
                ],
                "id": 1573
            }
        },
        {
            "score": 1.1439825,
            "fields": {
                "vector": [
                    0.9253267,
                    0.15890503,
                    0.7999555,
                    0.19126713,
                    0.898583
                ],
                "id": 1552
            }
        },
        {
            "score": 1.1029172,
            "fields": {
                "vector": [
                    0.95661926,
                    0.18777144,
                    0.38115507,
                    0.14323527,
                    0.93137646
                ],
                "id": 1823
            }
        }
    ],
    [
        {
            "score": 1.8005109,
            "fields": {
                "vector": [
                    0.5953582,
                    0.7794224,
                    0.9388869,
                    0.79825854,
                    0.9197286
                ],
                "id": 1888
            }
        },
        {
            "score": 1.7714822,
            "fields": {
                "vector": [
                    0.56805456,
                    0.89422905,
                    0.88187534,
                    0.914824,
                    0.8944365
                ],
                "id": 1648
            }
        },
        {
            "score": 1.7561421,
            "fields": {
                "vector": [
                    0.83421993,
                    0.39865613,
                    0.92319834,
                    0.42695504,
                    0.96633124
                ],
                "id": 1688
            }
        },
        {
            "score": 1.7553532,
            "fields": {
                "vector": [
                    0.89994013,
                    0.052991092,
                    0.8645576,
                    0.6406729,
                    0.95679337
                ],
                "id": 1573
            }
        },
        {
            "score": 1.7543385,
            "fields": {
                "vector": [
                    0.16542226,
                    0.38248396,
                    0.9888778,
                    0.80913955,
                    0.9501492
                ],
                "id": 1544
            }
        }
    ]
]}
[
  { score: 2.8421106338500977, id: '1745' },
  { score: 2.838560104370117, id: '1782' },
  { score: 2.8134000301361084, id: '1511' },
  { score: 2.718268871307373, id: '1679' },
  { score: 2.7014894485473633, id: '1597' }
]

Les données de red diffèrent de celles de blue. Par conséquent, les résultats de la recherche seront limités à la partition spécifiée, reflétant les caractéristiques uniques et la distribution des données de ce sous-ensemble.

Recherche avec champs de sortie

La recherche avec champs de sortie vous permet de spécifier quels attributs ou champs des vecteurs correspondants doivent être inclus dans les résultats de la recherche.

Vous pouvez spécifier output_fields dans une requête pour obtenir des résultats avec des champs spécifiques.

Voici un exemple de résultats renvoyant des valeurs d'attribut color:

# Search with output fields
res = client.search(
    collection_name="quick_setup", # Replace with the actual name of your collection
    data=[[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]],
    limit=5, # Max. number of search results to return
    search_params={"metric_type": "IP", "params": {}}, # Search parameters
    output_fields=["color"] # Output fields to return
)

result = json.dumps(res, indent=4)
print(result)
// 7. Search with output fields
query_vectors = Arrays.asList(Arrays.asList(0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f));

searchReq = SearchReq.builder()
    .collectionName("quick_setup")
    .data(query_vectors)
    .outputFields(Arrays.asList("color"))
    .topK(5)
    .build();

searchResp = client.search(searchReq);

System.out.println(JSONObject.toJSON(searchResp));
// 7. Search with output fields
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]

res = await client.search({
    collection_name: "quick_setup",
    data: [query_vector],
    limit: 5,
    output_fields: ["color"],
})

console.log(res.results)

La sortie est similaire à ce qui suit :

[
    [
        {
            "id": 0,
            "distance": 1.4093276262283325,
            "entity": {
                "color": "pink_8682"
            }
        },
        {
            "id": 16,
            "distance": 1.0159327983856201,
            "entity": {
                "color": "yellow_1496"
            }
        },
        {
            "id": 4,
            "distance": 0.9902134537696838,
            "entity": {
                "color": "red_4794"
            }
        },
        {
            "id": 14,
            "distance": 0.9803846478462219,
            "entity": {
                "color": "green_2899"
            }
        },
        {
            "id": 1,
            "distance": 0.8519943356513977,
            "entity": {
                "color": "red_7025"
            }
        }
    ]
]
{"searchResults": [
    [
        {
            "score": 1.263043,
            "fields": {}
        },
        {
            "score": 1.2377806,
            "fields": {}
        },
        {
            "score": 1.1869997,
            "fields": {}
        },
        {
            "score": 1.1748955,
            "fields": {}
        },
        {
            "score": 1.1720343,
            "fields": {}
        }
    ]
]}

[
  { score: 3.036271572113037, id: '59', color: 'orange' },
  { score: 3.0267879962921143, id: '1745', color: 'blue' },
  { score: 3.0069446563720703, id: '854', color: 'black' },
  { score: 2.984386682510376, id: '718', color: 'black' },
  { score: 2.916019916534424, id: '425', color: 'purple' }
]

Outre les voisins les plus proches, les résultats de la recherche comprennent le champ spécifié color, ce qui permet d'obtenir un ensemble d'informations plus riche pour chaque vecteur correspondant.

La recherche filtrée applique des filtres scalaires aux recherches vectorielles, ce qui vous permet d'affiner les résultats de la recherche en fonction de critères spécifiques. Vous trouverez plus d'informations sur les expressions de filtre dans Règles d'expression booléenne et des exemples dans Obtenir et requête scalaire.

Utiliser l'opérateur like

L'opérateur like améliore les recherches de chaînes de caractères en évaluant des motifs comprenant des préfixes, des infixes et des suffixes :

  • Correspondance de préfixes: pour trouver des valeurs commençant par un préfixe spécifique, utilisez la syntaxe 'like "prefix%"'.
  • Correspondance infixe: pour trouver des valeurs contenant une séquence spécifique de caractères n'importe où dans la chaîne, utilisez la syntaxe 'like "%infix%"'.
  • Correspondance de suffixe: pour trouver des valeurs se terminant par un suffixe spécifique, utilisez la syntaxe 'like "%suffix"'.

Pour la recherche d'un seul caractère, le trait de soulignement (_) agit comme un caractère de remplacement pour un seul caractère, par exemple 'like "y_llow"'.

Caractères spéciaux dans les chaînes de recherche

Si vous souhaitez rechercher une chaîne contenant des caractères spéciaux tels que des traits de soulignement (_) ou des signes de pourcentage (%), qui sont normalement utilisés comme caractères génériques dans les modèles de recherche (_ pour tout caractère unique et % pour toute séquence de caractères), vous devez échapper ces caractères pour les traiter comme des caractères littéraux. Utilisez une barre oblique inverse (\) pour échapper aux caractères spéciaux et n'oubliez pas d'échapper à la barre oblique inverse elle-même. Par exemple :

  • Pour rechercher un trait de soulignement littéral, utilisez \\_.
  • Pour rechercher un signe de pourcentage littéral, utilisez \\%.

Ainsi, si vous devez rechercher le texte "_version_", votre requête doit être formatée comme 'like "\\_version\\_"' pour que les traits de soulignement soient traités comme une partie du terme de recherche et non comme des caractères génériques.

Filtrer les résultats dont la couleur est préfixée en rouge:

# Search with filter
res = client.search(
    collection_name="quick_setup", # Replace with the actual name of your collection
    data=[[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]],
    limit=5, # Max. number of search results to return
    search_params={"metric_type": "IP", "params": {}}, # Search parameters
    output_fields=["color"], # Output fields to return
    filter='color like "red%"'
)

result = json.dumps(res, indent=4)
print(result)
// 8. Filtered search
query_vectors = Arrays.asList(Arrays.asList(0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f));

searchReq = SearchReq.builder()
    .collectionName("quick_setup")
    .data(query_vectors)
    .outputFields(Arrays.asList("color_tag"))
    .filter("color_tag like \"red%\"")
    .topK(5)
    .build();

searchResp = client.search(searchReq);

System.out.println(JSONObject.toJSON(searchResp));
// 8. Filtered search
// 8.1 Filter with "like" operator and prefix wildcard
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]

res = await client.search({
    collection_name: "quick_setup",
    data: [query_vector],
    limit: 5,
    filters: "color_tag like \"red%\"",
    output_fields: ["color_tag"]
})

console.log(res.results)

La sortie est similaire à ce qui suit :

[
    [
        {
            "id": 4,
            "distance": 0.9902134537696838,
            "entity": {
                "color": "red_4794"
            }
        },
        {
            "id": 1,
            "distance": 0.8519943356513977,
            "entity": {
                "color": "red_7025"
            }
        },
        {
            "id": 6,
            "distance": -0.4113418459892273,
            "entity": {
                "color": "red_9392"
            }
        }
    ]
]
{"searchResults": [
    [
        {
            "score": 1.1869997,
            "fields": {"color_tag": "red_3026"}
        },
        {
            "score": 1.1677284,
            "fields": {"color_tag": "red_9030"}
        },
        {
            "score": 1.1476475,
            "fields": {"color_tag": "red_3744"}
        },
        {
            "score": 1.0969629,
            "fields": {"color_tag": "red_4168"}
        },
        {
            "score": 1.0741848,
            "fields": {"color_tag": "red_9678"}
        }
    ]
]}
[
  { score: 2.5080761909484863, id: '1201', color_tag: 'red_8904' },
  { score: 2.491129159927368, id: '425', color_tag: 'purple_8212' },
  { score: 2.4889798164367676, id: '1458', color_tag: 'red_6891' },
  { score: 2.42964243888855, id: '724', color_tag: 'black_9885' },
  { score: 2.4004223346710205, id: '854', color_tag: 'black_5990' }
]

Filtre les résultats dont la couleur contient les lettres ll n'importe où dans la chaîne :

# Infix match on color field
res = client.search(
    collection_name="quick_setup", # Replace with the actual name of your collection
    data=[[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]],
    limit=5, # Max. number of search results to return
    search_params={"metric_type": "IP", "params": {}}, # Search parameters
    output_fields=["color"], # Output fields to return
    filter='color like "%ll%"' # Filter on color field, infix match on "ll"
)

result = json.dumps(res, indent=4)
print(result)
// 8. Filtered search
query_vectors = Arrays.asList(Arrays.asList(0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f));

searchReq = SearchReq.builder()
    .collectionName("quick_setup")
    .data(query_vectors)
    .outputFields(Arrays.asList("color_tag"))
    .filter("color like \"%ll%\"")
    .topK(5)
    .build();

searchResp = client.search(searchReq);

System.out.println(JSONObject.toJSON(searchResp));
// 8. Filtered search
// 8.1 Filter with "like" operator and prefix wildcard
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]

res = await client.search({
    collection_name: "quick_setup",
    data: [query_vector],
    limit: 5,
    filters: "color_tag like \"%ll%\"",
    output_fields: ["color_tag"]
})

console.log(res.results)

La sortie est similaire à ce qui suit :

[
    [
        {
            "id": 5,
            "distance": 0.7972343564033508,
            "entity": {
                "color": "yellow_4222"
            }
        }
    ]
]
{"searchResults": [
    [
        {
            "score": 1.1869997,
            "fields": {"color_tag": "yellow_4222"}
        }
    ]
]}
[
  { score: 2.5080761909484863, id: '1201', color_tag: 'yellow_4222' }
]

La recherche par plage vous permet de trouver des vecteurs qui se situent dans une plage de distance spécifiée par rapport à votre vecteur d'interrogation.

En définissant radius et éventuellement range_filter, vous pouvez ajuster l'étendue de votre recherche pour inclure des vecteurs qui sont quelque peu similaires au vecteur d'interrogation, ce qui permet d'obtenir une vue plus complète des correspondances potentielles.

  • radius: Définit la limite extérieure de votre espace de recherche. Seuls les vecteurs situés à cette distance du vecteur d'interrogation sont considérés comme des correspondances potentielles.

  • range_filter: Alors que radius définit la limite extérieure de la recherche, range_filter peut être utilisé de manière facultative pour définir une limite intérieure, en créant une plage de distances dans laquelle les vecteurs doivent se situer pour être considérés comme des correspondances.

# Conduct a range search
search_params = {
    "metric_type": "IP",
    "params": {
        "radius": 0.8, # Radius of the search circle
        "range_filter": 1.0 # Range filter to filter out vectors that are not within the search circle
    }
}

res = client.search(
    collection_name="quick_setup", # Replace with the actual name of your collection
    data=[[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]],
    limit=3, # Max. number of search results to return
    search_params=search_params, # Search parameters
    output_fields=["color"], # Output fields to return
)

result = json.dumps(res, indent=4)
print(result)
// 9. Range search
query_vectors = Arrays.asList(Arrays.asList(0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f));

searchReq = SearchReq.builder()
    .collectionName("quick_setup")
    .data(query_vectors)
    .outputFields(Arrays.asList("color_tag"))
    .searchParams(Map.of("radius", 0.1, "range", 1.0))
    .topK(5)
    .build();

searchResp = client.search(searchReq);

System.out.println(JSONObject.toJSON(searchResp));
// 9. Range search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]

res = await client.search({
    collection_name: "quick_setup",
    data: [query_vector],
    limit: 5,
    params: {
        radius: 0.1,
        range: 1.0
    },
    output_fields: ["color_tag"]
})

console.log(res.results)

La sortie est similaire à ce qui suit :

[
    [
        {
            "id": 4,
            "distance": 0.9902134537696838,
            "entity": {
                "color": "red_4794"
            }
        },
        {
            "id": 14,
            "distance": 0.9803846478462219,
            "entity": {
                "color": "green_2899"
            }
        },
        {
            "id": 1,
            "distance": 0.8519943356513977,
            "entity": {
                "color": "red_7025"
            }
        }
    ]
]
{"searchResults": [
    [
        {
            "score": 1.263043,
            "fields": {"color_tag": "green_2052"}
        },
        {
            "score": 1.2377806,
            "fields": {"color_tag": "purple_3709"}
        },
        {
            "score": 1.1869997,
            "fields": {"color_tag": "red_3026"}
        },
        {
            "score": 1.1748955,
            "fields": {"color_tag": "black_1646"}
        },
        {
            "score": 1.1720343,
            "fields": {"color_tag": "green_4853"}
        }
    ]
]}
[
  { score: 2.3387961387634277, id: '718', color_tag: 'black_7154' },
  { score: 2.3352415561676025, id: '1745', color_tag: 'blue_8741' },
  { score: 2.290485382080078, id: '1408', color_tag: 'red_2324' },
  { score: 2.285870313644409, id: '854', color_tag: 'black_5990' },
  { score: 2.2593345642089844, id: '1309', color_tag: 'red_8458' }
]

Vous constaterez que toutes les entités renvoyées ont une distance comprise entre 0,8 et 1,0 par rapport au vecteur de la requête.

Les paramètres de radius et range_filter varient en fonction du type de métrique utilisé.

Type de métriqueCaractéristiquesPlage Paramètres de recherche
L2Des distances L2 plus faibles indiquent une plus grande similarité.Pour exclure les vecteurs les plus proches des résultats, assurez-vous que :
range_filter <= distance < radius
IPDes distances IP plus grandes indiquent une plus grande similarité.Pour exclure les vecteurs les plus proches des résultats, assurez-vous que :
radius < distance <= range_filter
COSINEUne valeur de cosinus plus élevée indique une plus grande similarité.Pour exclure les vecteurs les plus proches des résultats, assurez-vous que :
radius < distance <= range_filter
JACCARDDes distances de Jaccard plus faibles indiquent une plus grande similarité.Pour exclure les vecteurs les plus proches des résultats, assurez-vous que :
range_filter <= distance < radius
HAMMINGDes distances de Hamming plus faibles indiquent une plus grande similarité.Pour exclure les vecteurs les plus proches des résultats, assurez-vous que :
range_filter <= distance < radius

Pour en savoir plus sur les types de métriques de distance, reportez-vous à la section Métriques de similarité.

Dans Milvus, la recherche par regroupement est conçue pour améliorer l'exhaustivité et la précision des résultats de recherche.

Considérons un scénario dans RAG, où des charges de documents sont divisées en divers passages, et où chaque passage est représenté par un vecteur intégré. Les utilisateurs souhaitent trouver les passages les plus pertinents afin de déclencher les MLD avec précision. La fonction de recherche ordinaire de Milvus peut répondre à cette exigence, mais elle peut produire des résultats très biaisés : la plupart des passages ne proviennent que de quelques documents, et l'exhaustivité des résultats de la recherche est très faible. Cela peut sérieusement nuire à la précision, voire à l'exactitude des résultats fournis par le LLM et influencer négativement l'expérience des utilisateurs du LLM.

La recherche groupée peut résoudre efficacement ce problème. En passant un champ group_by_field et group_size, les utilisateurs de Milvus peuvent répartir les résultats de la recherche en plusieurs groupes et s'assurer que le nombre d'entités de chaque groupe ne dépasse pas un group_size spécifique. Cette fonction permet d'améliorer considérablement l'exhaustivité et l'équité des résultats de la recherche, ce qui améliore sensiblement la qualité des résultats du LLM.

Voici un exemple de code pour regrouper les résultats de recherche par champ :

# Connect to Milvus
client = MilvusClient(uri='http://localhost:19530') # Milvus server address

# Load data into collection
client.load_collection("group_search") # Collection name

# Group search results
res = client.search(
    collection_name="group_search", # Collection name
    data=[[0.14529211512077012, 0.9147257273453546, 0.7965055218724449, 0.7009258593102812, 0.5605206522382088]], # Query vector
    search_params={
    "metric_type": "L2",
    "params": {"nprobe": 10},
    }, # Search parameters
    limit=5, # Max. number of groups to return
    group_by_field="doc_id", # Group results by document ID
    group_size=2, # returned at most 2 passages per document, the default value is 1
    group_strict_size=True, # ensure every group contains exactly 3 passages
    output_fields=["doc_id", "passage_id"]
)

# Retrieve the values in the `doc_id` column
doc_ids = [result['entity']['doc_id'] for result in res[0]]
passage_ids = [result['entity']['passage_id'] for result in res[0]]

print(doc_ids)
print(passage_ids)

Le résultat est similaire à ce qui suit :

["doc_11", "doc_11", "doc_7", "doc_7", "doc_3", "doc_3", "doc_2", "doc_2", "doc_8", "doc_8"]
[5, 10, 11, 10, 9, 6, 5, 4, 9, 2]

Dans le résultat donné, on peut observer que pour chaque document, exactement deux passages sont extraits et qu'un total de 5 documents composent collectivement les résultats.

À titre de comparaison, commentons les paramètres liés au groupe et effectuons une recherche normale :

# Connect to Milvus
client = MilvusClient(uri='http://localhost:19530') # Milvus server address

# Load data into collection
client.load_collection("group_search") # Collection name

# Search without `group_by_field`
res = client.search(
    collection_name="group_search", # Collection name
    data=query_passage_vector, # Replace with your query vector
    search_params={
    "metric_type": "L2",
    "params": {"nprobe": 10},
    }, # Search parameters
    limit=5, # Max. number of search results to return
    # group_by_field="doc_id", # Group results by document ID
    # group_size=2, 
    # group_strict_size=True,
    output_fields=["doc_id", "passage_id"]
)

# Retrieve the values in the `doc_id` column
doc_ids = [result['entity']['doc_id'] for result in res[0]]
passage_ids = [result['entity']['passage_id'] for result in res[0]]

print(doc_ids)
print(passage_ids)

Le résultat est similaire à ce qui suit :

["doc_11", "doc_11", "doc_11", "doc_11", "doc_11"]
[1, 10, 3, 12, 9]

Dans le résultat donné, on peut observer que "doc_11" a complètement dominé les résultats de la recherche, éclipsant les paragraphes de haute qualité des autres documents, ce qui peut être une mauvaise incitation au LLM.

Un dernier point à noter : par défaut, grouping_search renvoie les résultats instantanément lorsqu'il a suffisamment de groupes, ce qui peut conduire à ce que le nombre de résultats dans chaque groupe ne soit pas suffisant pour répondre à la taille du groupe (group_size). Si vous vous souciez du nombre de résultats pour chaque groupe, définissez group_strict_size=True comme indiqué dans le code ci-dessus. Milvus s'efforcera alors d'obtenir suffisamment de résultats pour chaque groupe, au prix d'une légère baisse des performances.

Limitations

  • Indexation: Cette fonction de regroupement ne fonctionne que pour les collections indexées avec le type HNSW, IVF_FLAT ou FLAT. Pour plus d'informations, reportez-vous à la section Index en mémoire.

  • Vecteur: Actuellement, la recherche par regroupement ne prend pas en charge les champs vectoriels de type BINARY_VECTOR. Pour plus d'informations sur les types de données, voir Types de données pris en charge.

  • Champ: Actuellement, la recherche par regroupement n'autorise qu'une seule colonne. Vous ne pouvez pas spécifier plusieurs noms de champs dans la configuration de group_by_field. En outre, la recherche groupée est incompatible avec les types de données JSON, FLOAT, DOUBLE, ARRAY ou les champs vectoriels.

  • Impact sur les performances: Soyez conscient que les performances se dégradent avec l'augmentation du nombre de vecteurs de requête. Si l'on prend l'exemple d'un cluster doté de 2 cœurs de CPU et de 8 Go de mémoire, le temps d'exécution de la recherche par regroupement augmente proportionnellement au nombre de vecteurs de requête en entrée.

  • Fonctionnalité: Actuellement, la recherche par regroupement n'est pas prise en charge par la recherche d'intervalle, les itérateurs de recherche et la recherche en ligne.

Paramètres de recherche

Dans les recherches ci-dessus, à l'exception de la recherche par plage, les paramètres de recherche par défaut s'appliquent. Dans les cas normaux, il n'est pas nécessaire de définir manuellement les paramètres de recherche.

# In normal cases, you do not need to set search parameters manually
# Except for range searches.
search_parameters = {
    'metric_type': 'L2',
    'params': {
        'nprobe': 10,
        'level': 1'radius': 1.0
        'range_filter': 0.8
    }
}

Le tableau suivant répertorie tous les réglages possibles des paramètres de recherche.

Nom du paramètreDescription du paramètre
metric_typeComment mesurer la similarité entre les intégrations vectorielles.
Les valeurs possibles sont IP, L2, COSINE, JACCARD, et HAMMING, et la valeur par défaut est celle du fichier d'index chargé.
params.nprobeNombre d'unités à interroger pendant la recherche.
La valeur est comprise entre [1, nlist[1]].
params.levelNiveau de précision de la recherche.
Les valeurs possibles sont 1, 2, et 3, et la valeur par défaut est 1. Des valeurs plus élevées donnent des résultats plus précis mais des performances plus lentes.
params.radiusDéfinit la limite extérieure de l'espace de recherche. Seuls les vecteurs situés à cette distance du vecteur de la requête sont considérés comme des correspondances potentielles.
La plage de valeurs est déterminée par le paramètre metric_type. Par exemple, si metric_type est défini sur L2, la plage de valeurs valide est [0, ∞]. Si metric_type est défini sur COSINE, la plage de valeurs valide est [-1, 1]. Pour plus d'informations, reportez-vous à la section Mesures de similarité.
params.range_filterAlors que radius définit la limite extérieure de la recherche, range_filter peut être utilisé en option pour définir une limite intérieure, en créant une plage de distances dans laquelle les vecteurs doivent se situer pour être considérés comme des correspondances.
La plage de valeurs est déterminée par le paramètre metric_type. Par exemple, si metric_type est défini sur L2, la plage de valeurs valide est [0, ∞]. Si metric_type est défini sur COSINE, la plage de valeurs valide est [-1, 1]. Pour plus d'informations, reportez-vous à la section Mesures de similarité.

notes

[1] Nombre d'unités de cluster après indexation. Lors de l'indexation d'une collection, Milvus subdivise les données vectorielles en plusieurs unités de cluster, dont le nombre varie en fonction des paramètres d'indexation actuels.

[2] Nombre d'entités à retourner lors d'une recherche.

Traduit parDeepLogo

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

Cette page a-t - elle été utile ?