Einzelvektor-Suche
Nachdem Sie Ihre Daten eingefügt haben, besteht der nächste Schritt darin, eine Ähnlichkeitssuche in Ihrer Sammlung in Milvus durchzuführen.
Milvus ermöglicht Ihnen die Durchführung von zwei Arten von Suchen, je nach Anzahl der Vektorfelder in Ihrer Sammlung:
- Einzelvektor-Suche: Wenn Ihre Sammlung nur ein Vektorfeld hat, verwenden Sie die
search()
Methode, um die ähnlichsten Entitäten zu finden. Diese Methode vergleicht Ihren Abfragevektor mit den vorhandenen Vektoren in Ihrer Sammlung und gibt die IDs der engsten Übereinstimmungen zusammen mit den Abständen zwischen ihnen zurück. Optional kann sie auch die Vektorwerte und Metadaten der Ergebnisse zurückgeben. - Hybride Suche: Für Sammlungen mit zwei oder mehr Vektorfeldern, verwenden Sie die
hybrid_search()
Methode. Diese Methode führt mehrere ANN-Suchanfragen (Approximate Nearest Neighbor) durch und kombiniert die Ergebnisse, um die relevantesten Übereinstimmungen nach einem Reranking zurückzugeben.
Diese Anleitung konzentriert sich auf die Durchführung einer Einzelvektorsuche in Milvus. Einzelheiten zur Hybrid-Suche finden Sie unter Hybrid-Suche.
Überblick
Es gibt eine Vielzahl von Suchtypen, die unterschiedlichen Anforderungen gerecht werden:
Einfache Suche: Umfasst die Einzelvektorsuche, die Massenvektorsuche, die Partitionssuche und die Suche mit bestimmten Ausgabefeldern.
Gefilterte Suche: Wendet Filterkriterien an, die auf skalaren Feldern basieren, um die Suchergebnisse zu verfeinern.
Bereichssuche: Findet Vektoren innerhalb eines bestimmten Abstandsbereichs vom Abfragevektor.
Gruppierungssuche: Gruppiert Suchergebnisse auf der Grundlage eines bestimmten Feldes, um die Vielfalt der Ergebnisse zu gewährleisten.
Vorbereitungen
Das folgende Codeschnipsel verwendet den bestehenden Code weiter, um eine Verbindung zu Milvus herzustellen und eine Sammlung schnell einzurichten.
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
//
Einfache Suche
Wenn Sie eine search
Anfrage senden, können Sie einen oder mehrere Vektorwerte angeben, die Ihre Abfrageeinbettungen darstellen, sowie einen limit
Wert, der die Anzahl der zurückzugebenden Ergebnisse angibt.
Abhängig von Ihren Daten und Ihrem Abfragevektor erhalten Sie möglicherweise weniger als limit
Ergebnisse. Dies geschieht, wenn limit
größer ist als die Anzahl der möglichen übereinstimmenden Vektoren für Ihre Abfrage.
Ein-Vektor-Suche
Die Ein-Vektor-Suche ist die einfachste Form der search
Operationen in Milvus und dient dazu, die ähnlichsten Vektoren zu einem bestimmten Abfragevektor zu finden.
Um eine Einzelvektorsuche durchzuführen, geben Sie den Namen der Zielsammlung, den Abfragevektor und die gewünschte Anzahl von Ergebnissen an (limit
). Dieser Vorgang gibt eine Ergebnismenge zurück, die die ähnlichsten Vektoren, ihre IDs und Abstände zum Abfragevektor enthält.
Hier ein Beispiel für die Suche nach den Top 5 Entitäten, die dem Abfragevektor am ähnlichsten sind:
# 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)
Parameter | Beschreibung |
---|---|
collection_name |
Der Name einer bestehenden Sammlung. |
data |
Eine Liste von Vektoreinbettungen. Milvus sucht nach den Vektoreinbettungen, die den angegebenen am ähnlichsten sind. |
limit |
Die Gesamtzahl der zurückzugebenden Entitäten. Sie können diesen Parameter in Kombination mit offset in param verwenden, um die Paginierung zu aktivieren. Die Summe aus diesem Wert und offset in param sollte kleiner als 16.384 sein. |
search_params |
Die spezifischen Parametereinstellungen für diesen Vorgang.
|
Parameter | Beschreibung |
---|---|
collectionName |
Der Name einer bestehenden Sammlung. |
data |
Eine Liste von Vektoreinbettungen. Milvus sucht nach den Vektoreinbettungen, die den angegebenen am ähnlichsten sind. |
topK |
Die Anzahl der Datensätze, die im Suchergebnis zurückgegeben werden sollen. Dieser Parameter verwendet dieselbe Syntax wie der Parameter limit, so dass Sie nur einen der beiden Parameter setzen sollten. Sie können diesen Parameter in Kombination mit offset in param verwenden, um die Paginierung zu aktivieren. Die Summe aus diesem Wert und offset in param sollte kleiner als 16.384 sein. |
Parameter | Beschreibung |
---|---|
collection_name |
Der Name einer bestehenden Sammlung. |
data |
Eine Liste von Vektoreinbettungen. Milvus sucht nach den Vektoreinbettungen, die den angegebenen am ähnlichsten sind. |
limit |
Die Gesamtzahl der zurückzugebenden Entitäten. Sie können diesen Parameter in Kombination mit offset in param verwenden, um die Paginierung zu aktivieren. Die Summe aus diesem Wert und offset in param sollte kleiner als 16.384 sein. |
Die Ausgabe ist ähnlich wie die folgende:
[
[
{
"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' }
]
Die Ausgabe zeigt die Top 5 Nachbarn, die Ihrem Abfragevektor am nächsten sind, einschließlich ihrer eindeutigen IDs und der berechneten Abstände.
Bulk-Vektor-Suche
Die Massenvektorsuche erweitert das Konzept der Einzelvektorsuche, indem sie die Suche nach mehreren Abfragevektoren in einer einzigen Anfrage ermöglicht. Diese Art der Suche ist ideal für Szenarien, in denen ähnliche Vektoren für eine Reihe von Abfragevektoren gefunden werden müssen, was den Zeit- und Rechenaufwand erheblich reduziert.
Bei einer Massenvektorsuche können Sie mehrere Abfragevektoren in das Feld data
aufnehmen. Das System verarbeitet diese Vektoren parallel und gibt für jeden Abfragevektor einen separaten Ergebnissatz zurück, wobei jeder Satz die engsten Übereinstimmungen enthält, die in der Sammlung gefunden wurden.
Hier ist ein Beispiel für die Suche nach zwei verschiedenen Gruppen der ähnlichsten Entitäten aus zwei Abfragevektoren:
# 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)
Die Ausgabe ist ähnlich wie die folgende:
[
[
{
"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' }
]
]
Die Ergebnisse umfassen zwei Sätze nächster Nachbarn, einen für jeden Abfragevektor, was die Effizienz der Massenvektorsuche bei der gleichzeitigen Bearbeitung mehrerer Abfragevektoren verdeutlicht.
Partitionierte Suche
Die Partitionssuche grenzt den Umfang Ihrer Suche auf eine bestimmte Teilmenge oder Partition Ihrer Sammlung ein. Dies ist besonders nützlich für organisierte Datensätze, bei denen die Daten in logische oder kategorische Unterteilungen segmentiert sind, was schnellere Suchvorgänge ermöglicht, da die zu durchsuchende Datenmenge reduziert wird.
Um eine Partitionssuche durchzuführen, geben Sie einfach den Namen der Zielpartition unter partition_names
in Ihrer Suchanfrage an. Dadurch wird festgelegt, dass die Operation search
nur Vektoren innerhalb der angegebenen Partition berücksichtigt.
Hier ist ein Beispiel für die Suche nach Entitäten in 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)
Die Ausgabe ist ähnlich wie die folgende:
[
[
{
"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' }
]
Suchen Sie dann nach Entitäten in 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)
Die Ausgabe ist ähnlich wie die folgende:
[
[
{
"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' }
]
Die Daten in red
unterscheiden sich von denen in blue
. Daher werden die Suchergebnisse auf die angegebene Partition beschränkt und spiegeln die einzigartigen Merkmale und die Datenverteilung dieser Untergruppe wider.
Suche mit Ausgabefeldern
Bei der Suche mit Ausgabefeldern können Sie angeben, welche Attribute oder Felder der übereinstimmenden Vektoren in die Suchergebnisse aufgenommen werden sollen.
Sie können output_fields
in einer Anfrage angeben, um Ergebnisse mit bestimmten Feldern zu erhalten.
Hier ist ein Beispiel für die Rückgabe von Ergebnissen mit color
Attributwerten:
# 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)
Die Ausgabe ist ähnlich wie die folgende:
[
[
{
"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' }
]
Die Suchergebnisse enthalten neben den nächsten Nachbarn auch das angegebene Feld color
und bieten somit einen umfangreicheren Satz an Informationen für jeden passenden Vektor.
Gefilterte Suche
Die gefilterte Suche wendet skalare Filter auf die Vektorsuche an und ermöglicht es Ihnen, die Suchergebnisse anhand bestimmter Kriterien zu verfeinern. Weitere Informationen zu Filterausdrücken finden Sie unter Boolesche Ausdrucksregeln und Beispiele unter Hole & Skalare Abfrage.
Verwenden Sie den like
Operator
Der like
Operator verbessert die Zeichenkettensuche durch die Auswertung von Mustern, einschließlich Präfixen, Infixen und Suffixen:
- Präfixabgleich: Um Werte zu finden, die mit einem bestimmten Präfix beginnen, verwenden Sie die Syntax
'like "prefix%"'
. - Infix-Abgleich: Um Werte zu finden, die eine bestimmte Zeichenfolge an beliebiger Stelle in der Zeichenkette enthalten, verwenden Sie die Syntax
'like "%infix%"'
. - Suffix-Abgleich: Um Werte zu finden, die mit einem bestimmten Suffix enden, verwenden Sie die Syntax
'like "%suffix"'
.
Bei der Suche nach einzelnen Zeichen dient der Unterstrich (_
) als Platzhalter für ein Zeichen, z. B. 'like "y_llow"'
.
Sonderzeichen in Suchzeichenketten
Wenn Sie nach einer Zeichenkette suchen wollen, die Sonderzeichen wie Unterstriche (_
) oder Prozentzeichen (%
) enthält, die normalerweise als Platzhalter in Suchmustern verwendet werden (_
für ein einzelnes Zeichen und %
für eine beliebige Folge von Zeichen), müssen Sie diese Zeichen mit einem Escapezeichen versehen, um sie als literale Zeichen zu behandeln. Verwenden Sie einen Backslash (\
), um Sonderzeichen zu entschlüsseln, und denken Sie daran, den Backslash selbst zu entschlüsseln. Ein Beispiel:
- Um nach einem buchstäblichen Unterstrich zu suchen, verwenden Sie
\\_
. - Um nach einem wörtlichen Prozentzeichen zu suchen, verwenden Sie
\\%
.
Wenn Sie also nach dem Text "_version_"
suchen müssen, sollte Ihre Abfrage als 'like "\\_version\\_"'
formatiert werden, um sicherzustellen, dass die Unterstriche als Teil des Suchbegriffs und nicht als Platzhalter behandelt werden.
Filtern Sie Ergebnisse, deren Farbe mit einem roten Präfix versehen ist:
# 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)
Die Ausgabe ist ähnlich wie die folgende:
[
[
{
"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' }
]
Filtert Ergebnisse, deren Farbe die Buchstaben ll an einer beliebigen Stelle der Zeichenkette enthält:
# 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)
Die Ausgabe ist ähnlich wie die folgende:
[
[
{
"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' }
]
Bereichssuche
Die Bereichssuche ermöglicht es Ihnen, Vektoren zu finden, die innerhalb eines bestimmten Abstandsbereichs zu Ihrem Abfragevektor liegen.
Durch Einstellen von radius
und optional range_filter
können Sie die Breite Ihrer Suche so anpassen, dass auch Vektoren einbezogen werden, die dem Abfragevektor einigermaßen ähnlich sind, und so eine umfassendere Übersicht über mögliche Übereinstimmungen erhalten.
radius
: Legt die äußere Grenze des Suchraums fest. Nur Vektoren, die innerhalb dieses Abstands zum Abfragevektor liegen, werden als potenzielle Übereinstimmungen betrachtet.range_filter
: Währendradius
die äußere Grenze der Suche festlegt, kannrange_filter
optional verwendet werden, um eine innere Grenze zu definieren und einen Abstandsbereich zu schaffen, in den Vektoren fallen müssen, um als Treffer zu gelten.
# 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)
Die Ausgabe ist ähnlich wie die folgende:
[
[
{
"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' }
]
Sie werden feststellen, dass alle zurückgegebenen Entitäten einen Abstand zwischen 0,8 und 1,0 vom Abfragevektor haben.
Die Parametereinstellungen für radius
und range_filter
variieren je nach verwendetem metrischen Typ.
Metrischer Typ | Charakteristiken | Bereich Sucheinstellungen |
---|---|---|
L2 | Kleinere L2-Distanzen zeigen eine höhere Ähnlichkeit an. | Um die nächstgelegenen Vektoren von den Ergebnissen auszuschließen, stellen Sie sicher, dass:range_filter <= distance < radius |
IP | Größere IP-Distanzen weisen auf eine höhere Ähnlichkeit hin. | Um die nächstgelegenen Vektoren von den Ergebnissen auszuschließen, stellen Sie sicher, dass:radius <= distance <= range_filter |
COSINE | Ein größerer Kosinuswert deutet auf eine größere Ähnlichkeit hin. | Um die engsten Vektoren von den Ergebnissen auszuschließen, stellen Sie sicher, dass:radius < Abstand <= range_filter |
JACCARD | Kleinere Jaccard-Distanzen weisen auf eine höhere Ähnlichkeit hin. | Um die nächstgelegenen Vektoren aus den Ergebnissen auszuschließen, stellen Sie sicher, dass:range_filter <= distance < radius |
HAMMING | Kleinere Hamming-Distanzen weisen auf eine höhere Ähnlichkeit hin. | Um die nächstgelegenen Vektoren aus den Ergebnissen auszuschließen, stellen Sie sicher, dass:range_filter <= distance < radius |
Weitere Informationen über die Arten von Abstandsmetriken finden Sie unter Ähnlichkeitsmetriken.
Gruppierungssuche
In Milvus wurde die Gruppierungssuche entwickelt, um die Vollständigkeit und Genauigkeit der Suchergebnisse zu verbessern.
Stellen Sie sich ein Szenario in RAG vor, in dem eine Menge von Dokumenten in verschiedene Passagen aufgeteilt ist und jede Passage durch eine Vektoreinbettung dargestellt wird. Die Benutzer möchten die relevantesten Passagen finden, um die LLMs genau abzufragen. Die gewöhnliche Milvus-Suchfunktion kann diese Anforderung erfüllen, aber sie kann zu stark verzerrten und voreingenommenen Ergebnissen führen: Die meisten Passagen stammen aus nur wenigen Dokumenten, und die Vollständigkeit der Suchergebnisse ist sehr gering. Dies kann die Genauigkeit oder sogar die Korrektheit der vom LLM gelieferten Ergebnisse ernsthaft beeinträchtigen und die Erfahrung der LLM-Nutzer negativ beeinflussen.
Die Gruppensuche kann dieses Problem wirksam lösen. Durch Übergabe eines group_by_field und group_size können Milvus-Benutzer die Suchergebnisse in mehrere Gruppen aufteilen und sicherstellen, dass die Anzahl der Entitäten aus jeder Gruppe eine bestimmte group_size nicht überschreitet. Diese Funktion kann den Umfang und die Fairness der Suchergebnisse erheblich steigern und die Qualität der LLM-Ausgabe spürbar verbessern.
Hier ist der Beispielcode zum Gruppieren von Suchergebnissen nach Feld:
# 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)
Die Ausgabe ist ähnlich wie die folgende:
["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]
In der gegebenen Ausgabe ist zu sehen, dass für jedes Dokument genau zwei Passagen gefunden werden und insgesamt 5 Dokumente die Ergebnisse ausmachen.
Zum Vergleich kommentieren wir die gruppenbezogenen Parameter aus und führen eine reguläre Suche durch:
# 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)
Die Ausgabe ist ähnlich wie die folgende:
["doc_11", "doc_11", "doc_11", "doc_11", "doc_11"]
[1, 10, 3, 12, 9]
In der gegebenen Ausgabe ist zu beobachten, dass "doc_11" die Suchergebnisse vollständig dominiert und die qualitativ hochwertigen Absätze aus anderen Dokumenten überschattet, was eine schlechte Aufforderung an LLM sein kann.
Noch ein Hinweis: Standardmäßig gibt grouping_search sofort Ergebnisse zurück, wenn es genügend Gruppen hat, was dazu führen kann, dass die Anzahl der Ergebnisse in jeder Gruppe nicht ausreicht, um die group_size zu erfüllen. Wenn Ihnen die Anzahl der Ergebnisse für jede Gruppe wichtig ist, setzen Sie group_strict_size=True wie im obigen Code gezeigt. Dies führt dazu, dass Milvus sich bemüht, genügend Ergebnisse für jede Gruppe zu erhalten, was allerdings zu einem leichten Leistungsverlust führt.
Beschränkungen
Indizierung: Diese Gruppierungsfunktion funktioniert nur für Sammlungen, die mit dem HNSW-, IVF_FLAT- oder FLAT-Typ indiziert sind. Weitere Informationen finden Sie unter In-Memory-Index.
Vektor: Derzeit unterstützt die Gruppierungssuche kein Vektorfeld vom Typ BINARY_VECTOR. Weitere Informationen zu Datentypen finden Sie unter Unterstützte Datentypen.
Feld: Derzeit ist bei der Gruppierungssuche nur eine einzige Spalte möglich. Sie können nicht mehrere Feldnamen in der Konfiguration
group_by_field
angeben. Außerdem ist die Gruppierungssuche nicht mit den Datentypen JSON, FLOAT, DOUBLE, ARRAY oder Vektorfeldern kompatibel.Auswirkungen auf die Leistung: Beachten Sie, dass die Leistung mit zunehmender Anzahl von Abfragevektoren abnimmt. Am Beispiel eines Clusters mit 2 CPU-Kernen und 8 GB Speicher steigt die Ausführungszeit für die Gruppierungssuche proportional zur Anzahl der Eingabeabfragevektoren.
Funktionsweise: Derzeit wird die Gruppierungssuche nicht von der Bereichssuche und den Suchitern unterstützt.
Suchparameter
Für die oben genannten Suchvorgänge, mit Ausnahme der Bereichssuche, gelten die Standardsuchparameter. Im Normalfall müssen Sie die Suchparameter nicht manuell einstellen.
# 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
}
}
In der folgenden Tabelle sind alle möglichen Einstellungen für die Suchparameter aufgeführt.
Parameter Name | Parameter Beschreibung |
---|---|
metric_type | Wie wird die Ähnlichkeit zwischen Vektoreinbettungen gemessen. Mögliche Werte sind IP , L2 , COSINE , JACCARD und HAMMING , und sind standardmäßig die der geladenen Indexdatei. |
params.nprobe | Anzahl der Einheiten, die während der Suche abgefragt werden. Der Wert fällt in den Bereich [1, nlist[1]]. |
params.level | Genauigkeitsgrad der Suche. Mögliche Werte sind 1 , 2 und 3 , der Standardwert ist 1 . Höhere Werte liefern genauere Ergebnisse, aber eine langsamere Leistung. |
params.radius | Legt die äußere Begrenzung des Suchraums fest. Nur Vektoren, die innerhalb dieses Abstands zum Abfragevektor liegen, werden als potenzielle Übereinstimmungen betrachtet. Der Wertebereich wird durch den Parameter metric_type bestimmt. Wenn metric_type beispielsweise auf L2 eingestellt ist, ist der gültige Wertebereich [0, ∞] . Wenn metric_type auf COSINE eingestellt ist, ist der gültige Wertebereich [-1, 1] . Weitere Informationen finden Sie unter Ähnlichkeitsmetriken. |
params.range_filter | Während radius die äußere Grenze der Suche festlegt, kann range_filter optional verwendet werden, um eine innere Grenze zu definieren und einen Abstandsbereich zu schaffen, in den Vektoren fallen müssen, um als übereinstimmend zu gelten.Der Wertebereich wird durch den Parameter metric_type bestimmt. Wenn beispielsweise metric_type auf L2 gesetzt ist, ist der gültige Wertebereich [0, ∞] . Wenn metric_type auf COSINE gesetzt ist, ist der gültige Wertebereich [-1, 1] . Weitere Informationen finden Sie unter Ähnlichkeitsmetriken. |
Hinweise
[1] Anzahl der Cluster-Einheiten nach der Indizierung. Bei der Indizierung einer Sammlung unterteilt Milvus die Vektordaten in mehrere Clustereinheiten, deren Anzahl von den aktuellen Indexeinstellungen abhängt.
[2] Anzahl der Entitäten, die bei einer Suche zurückgegeben werden.