Búsqueda vectorial básica
Basándose en un archivo de índice que registra el orden clasificado de las representaciones vectoriales, la búsqueda de «vecino más cercano aproximado» (ANN) localiza un subconjunto de representaciones vectoriales a partir del vector de consulta incluido en una solicitud de búsqueda recibida, compara el vector de consulta con los del subconjunto y devuelve los resultados más similares. Con la búsqueda ANN, Milvus ofrece una experiencia de búsqueda eficiente. Esta página te ayuda a aprender a realizar búsquedas ANN básicas.
Si se añaden nuevos campos después de haber creado la colección, las búsquedas que incluyan dichos campos devolverán los valores predeterminados definidos o « NULL » para aquellas entidades que no tengan valores establecidos explícitamente. Para obtener más información, consulta «Modificar el esquema de la colección».
Descripción general
La búsqueda ANN y la de k vecinos más cercanos (kNN) son los métodos habituales en las búsquedas de similitud vectorial. En una búsqueda kNN, es necesario comparar todos los vectores de un espacio vectorial con el vector de consulta incluido en la solicitud de búsqueda antes de determinar cuáles son los más similares, lo cual requiere mucho tiempo y consume muchos recursos.
A diferencia de las búsquedas kNN, un algoritmo de búsqueda ANN requiere un archivo de índice que registre el orden clasificado de las incrustaciones vectoriales. Cuando se recibe una solicitud de búsqueda, se puede utilizar el archivo de índice como referencia para localizar rápidamente un subgrupo que probablemente contenga las incrustaciones vectoriales más similares al vector de consulta. A continuación, puede utilizar el tipo de métrica especificado para medir la similitud entre el vector de consulta y los del subgrupo, ordenar los elementos del grupo en función de su similitud con el vector de consulta y determinar los K elementos principales del grupo.
Las búsquedas ANN dependen de índices predefinidos, y el rendimiento de la búsqueda, el uso de memoria y la precisión de la búsqueda pueden variar en función de los tipos de índice que se elijan. Es necesario encontrar un equilibrio entre el rendimiento y la precisión de la búsqueda.
Para reducir la curva de aprendizaje, Milvus ofrece AUTOINDEX. Con AUTOINDEX, Milvus puede analizar la distribución de los datos dentro de su colección mientras crea el índice y establece los parámetros de índice más optimizados basándose en el análisis, con el fin de lograr un equilibrio entre el rendimiento y la precisión de la búsqueda.
En esta sección, encontrarás información detallada sobre los siguientes temas:
Búsqueda de un solo vector
En las búsquedas con redes neuronales artificiales (ANN), una búsqueda de vector único es aquella en la que solo se utiliza un vector de consulta. Basándose en el índice predefinido y en el tipo de métrica incluido en la solicitud de búsqueda, Milvus encontrará los K vectores más similares al vector de consulta.
En esta sección, aprenderás a realizar una búsqueda de vector único. La solicitud de búsqueda incluye un único vector de consulta y pide a Milvus que utilice el producto interno (IP) para calcular la similitud entre los vectores de consulta y los vectores de la colección, devolviendo los tres más similares.
from pymilvus import MilvusClient
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus"
)
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
res = client.search(
collection_name="quick_setup",
anns_field="vector",
data=[query_vector],
limit=3,
search_params={"metric_type": "IP"}
)
for hits in res:
for hit in hits:
print(hit)
# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ]
# ]
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp;
import java.util.*;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.token("root:Milvus")
.build());
FloatVec queryVector = new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f});
SearchReq searchReq = SearchReq.builder()
.collectionName("quick_setup")
.data(Collections.singletonList(queryVector))
.annsField("vector")
.topK(3)
.build();
SearchResp searchResp = client.search(searchReq);
List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
System.out.println("TopK results:");
for (SearchResp.SearchResult result : results) {
System.out.println(result);
}
}
// Output
// TopK results:
// SearchResp.SearchResult(entity={}, score=0.95944905, id=5)
// SearchResp.SearchResult(entity={}, score=0.8689616, id=1)
// SearchResp.SearchResult(entity={}, score=0.866088, id=7)
import (
"context"
"fmt"
"github.com/milvus-io/milvus/client/v2/entity"
"github.com/milvus-io/milvus/client/v2/milvusclient"
)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
milvusAddr := "localhost:19530"
token := "root:Milvus"
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: milvusAddr,
APIKey: token,
})
if err != nil {
fmt.Println(err.Error())
// handle error
}
defer client.Close(ctx)
queryVector := []float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"quick_setup", // collectionName
3, // limit
[]entity.Vector{entity.FloatVector(queryVector)},
).WithANNSField("vector"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
}
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const address = "http://localhost:19530";
const token = "root:Milvus";
const client = new MilvusClient({address, token});
// 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)
// [
// { score: 0.08821295201778412, id: '551' },
// { score: 0.0800950899720192, id: '296' },
// { score: 0.07794742286205292, id: '43' }
// ]
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "quick_setup",
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
],
"annsField": "vector",
"limit": 3
}'
# {
# "code": 0,
# "data": [
# {
# "distance": 0.08821295201778412,
# "id": 551
# },
# {
# "distance": 0.0800950899720192,
# "id": 296
# },
# {
# "distance": 0.07794742286205292,
# "id": 43
# }
# ]
# }
Milvus clasifica los resultados de la búsqueda por orden descendente según sus puntuaciones de similitud con el vector de consulta. La puntuación de similitud también se denomina «distancia al vector de consulta», y sus rangos de valores varían en función de los tipos de métrica utilizados.
La siguiente tabla enumera los tipos de métricas aplicables y los rangos de distancia correspondientes.
Tipo de métrica |
Características |
Rango de distancia |
|---|---|---|
|
Un valor más pequeño indica una mayor similitud. |
[0, ∞) |
|
Un valor mayor indica una mayor similitud. |
[-1, 1] |
|
Un valor mayor indica una mayor similitud. |
[-1, 1] |
|
Un valor menor indica una mayor similitud. |
[0, 1] |
|
Un valor menor indica una mayor similitud. |
[0, dim(vector)] |
Búsqueda masiva de vectores
Del mismo modo, puedes incluir varios vectores de consulta en una solicitud de búsqueda. Milvus realizará búsquedas ANN para los vectores de consulta en paralelo y devolverá dos conjuntos de resultados.
# 7. Search with multiple vectors
# 7.1. Prepare query vectors
query_vectors = [
[0.041732933, 0.013779674, -0.027564144, -0.013061441, 0.009748648],
[0.0039737443, 0.003020432, -0.0006188639, 0.03913546, -0.00089768134]
]
# 7.2. Start search
res = client.search(
collection_name="quick_setup",
data=query_vectors,
limit=3,
)
for hits in res:
print("TopK results:")
for hit in hits:
print(hit)
# Output
#
# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ],
# [
# {
# "id": 730,
# "distance": 0.04431751370429993,
# "entity": {}
# },
# {
# "id": 333,
# "distance": 0.04231833666563034,
# "entity": {}
# },
# {
# "id": 232,
# "distance": 0.04221535101532936,
# "entity": {}
# }
# ]
# ]
import io.milvus.v2.service.vector.request.SearchReq
import io.milvus.v2.service.vector.request.data.BaseVector;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp
List<BaseVector> queryVectors = Arrays.asList(
new FloatVec(new float[]{0.041732933f, 0.013779674f, -0.027564144f, -0.013061441f, 0.009748648f}),
new FloatVec(new float[]{0.0039737443f, 0.003020432f, -0.0006188639f, 0.03913546f, -0.00089768134f})
);
SearchReq searchReq = SearchReq.builder()
.collectionName("quick_setup")
.data(queryVectors)
.topK(3)
.build();
SearchResp searchResp = client.search(searchReq);
List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
System.out.println("TopK results:");
for (SearchResp.SearchResult result : results) {
System.out.println(result);
}
}
// Output
// TopK results:
// SearchResp.SearchResult(entity={}, score=0.49548206, id=1)
// SearchResp.SearchResult(entity={}, score=0.320147, id=3)
// SearchResp.SearchResult(entity={}, score=0.107413776, id=6)
// TopK results:
// SearchResp.SearchResult(entity={}, score=0.5678123, id=6)
// SearchResp.SearchResult(entity={}, score=0.32368967, id=2)
// SearchResp.SearchResult(entity={}, score=0.24108477, id=3)
queryVectors := []entity.Vector{
entity.FloatVector([]float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}),
entity.FloatVector([]float32{0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104}),
}
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"quick_setup", // collectionName
3, // limit
queryVectors,
).WithConsistencyLevel(entity.ClStrong).
WithANNSField("vector"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
}
// 7. Search with multiple vectors
const 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",
vectors: query_vectors,
limit: 3,
})
console.log(res.results)
// Output
//
// [
// [
// { score: 0.08821295201778412, id: '551' },
// { score: 0.0800950899720192, id: '296' },
// { score: 0.07794742286205292, id: '43' }
// ],
// [
// { score: 0.04431751370429993, id: '730' },
// { score: 0.04231833666563034, id: '333' },
// { score: 0.04221535101532936, id: '232' },
// ]
// ]
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "quick_setup",
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104]
],
"annsField": "vector",
"limit": 3
}'
# {
# "code": 0,
# "data": [
# [
# {
# "distance": 0.08821295201778412,
# "id": 551
# },
# {
# "distance": 0.0800950899720192,
# "id": 296
# },
# {
# "distance": 0.07794742286205292,
# "id": 43
# }
# ],
# [
# {
# "distance": 0.04431751370429993,
# "id": 730
# },
# {
# "distance": 0.04231833666563034,
# "id": 333
# },
# {
# "distance": 0.04221535101532936,
# "id": 232
# }
# ]
# ],
# "topks":[3]
# }
Búsqueda por clave primariaCompatible with Milvus 2.6.9+
En lugar de establecer vectores de consulta, puedes utilizar claves primarias si los vectores de consulta ya existen en la colección de destino.
res = client.search(
collection_name="quick_setup",
anns_field="vector",
ids=[551, 296, 43],
limit=3,
search_params={"metric_type": "IP"}
)
for hits in res:
for hit in hits:
print(hit)
// java
// node.js
// go
# restful
curl -X POST "http://localhost:19530/v2/vectordb/entities/search" \
-H "Content-Type: application/json" \
-H "Request-Timeout: 10" \
-H "Authorization: Bearer root:Milvus" \
-d '{
"collectionName": "quick_setup",
"annsField": "vector",
"ids": [551, 296, 43],
"limit": 3,
"searchParams": {
"metric_type": "IP"
}
}'
Búsqueda ANN en particiones
Supongamos que has creado varias particiones en una colección y que puedes limitar el ámbito de la búsqueda a un número concreto de particiones. En ese caso, puedes incluir los nombres de las particiones de destino en la solicitud de búsqueda para restringir el ámbito de la búsqueda a las particiones especificadas. Reducir el número de particiones implicadas en la búsqueda mejora el rendimiento de la misma.
El siguiente fragmento de código da por hecho que existe una partición llamada PartitionA en su colección.
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
res = client.search(
collection_name="quick_setup",
partition_names=["partitionA"],
data=[query_vector],
limit=3,
)
for hits in res:
print("TopK results:")
for hit in hits:
print(hit)
# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ]
# ]
import io.milvus.v2.service.vector.request.SearchReq
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp
FloatVec queryVector = new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f});
SearchReq searchReq = SearchReq.builder()
.collectionName("quick_setup")
.partitionNames(Collections.singletonList("partitionA"))
.data(Collections.singletonList(queryVector))
.topK(3)
.build();
SearchResp searchResp = client.search(searchReq);
List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
System.out.println("TopK results:");
for (SearchResp.SearchResult result : results) {
System.out.println(result);
}
}
// Output
// TopK results:
// SearchResp.SearchResult(entity={}, score=0.6395302, id=13)
// SearchResp.SearchResult(entity={}, score=0.5408028, id=12)
// SearchResp.SearchResult(entity={}, score=0.49696884, id=17)
queryVector := []float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"quick_setup", // collectionName
3, // limit
[]entity.Vector{entity.FloatVector(queryVector)},
).WithConsistencyLevel(entity.ClStrong).
WithPartitions("partitionA").
WithANNSField("vector"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
}
// 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",
partition_names: ["partitionA"],
data: query_vector,
limit: 3, // The number of results to return
})
console.log(res.results)
// [
// { score: 0.08821295201778412, id: '551' },
// { score: 0.0800950899720192, id: '296' },
// { score: 0.07794742286205292, id: '43' }
// ]
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "quick_setup",
"partitionNames": ["partitionA"],
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
],
"annsField": "vector",
"limit": 3
}'
# {
# "code": 0,
# "data": [
# {
# "distance": 0.08821295201778412,
# "id": 551
# },
# {
# "distance": 0.0800950899720192,
# "id": 296
# },
# {
# "distance": 0.07794742286205292,
# "id": 43
# }
# ],
# "topks":[3]
# }
Uso de campos de salida
En un resultado de búsqueda, Milvus incluye, de forma predeterminada, los valores de los campos principales y las distancias o puntuaciones de similitud de las entidades que contienen las K mejores incrustaciones vectoriales. Puedes incluir los nombres de los campos de destino, tanto los campos vectoriales como los escalares, en una solicitud de búsqueda como campos de salida para que los resultados de la búsqueda incluyan los valores de otros campos de estas entidades.
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
res = client.search(
collection_name="quick_setup",
data=[query_vector],
limit=3, # The number of results to return
search_params={"metric_type": "IP"},
output_fields=["color"]
)
print(res)
# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {
# "color": "orange_6781"
# }
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {
# "color": "red_4794"
# }
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {
# "color": "grey_8510"
# }
# }
# ]
# ]
import io.milvus.v2.service.vector.request.SearchReq
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp
FloatVec queryVector = new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f});
SearchReq searchReq = SearchReq.builder()
.collectionName("quick_setup")
.data(Collections.singletonList(queryVector))
.topK(3)
.outputFields(Collections.singletonList("color"))
.build();
SearchResp searchResp = client.search(searchReq);
List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
System.out.println("TopK results:");
for (SearchResp.SearchResult result : results) {
System.out.println(result);
}
}
// Output
// TopK results:
// SearchResp.SearchResult(entity={color=black_9955}, score=0.95944905, id=5)
// SearchResp.SearchResult(entity={color=red_7319}, score=0.8689616, id=1)
// SearchResp.SearchResult(entity={color=white_5015}, score=0.866088, id=7)
queryVector := []float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"quick_setup", // collectionName
3, // limit
[]entity.Vector{entity.FloatVector(queryVector)},
).WithConsistencyLevel(entity.ClStrong).
WithANNSField("vector").
WithOutputFields("color"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
fmt.Println("color: ", resultSet.GetColumn("color").FieldData().GetScalars())
}
// 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
output_fields: ["color"]
})
console.log(res.results)
// [
// { score: 0.08821295201778412, id: '551', entity: {"color": "orange_6781"}},
// { score: 0.0800950899720192, id: '296' entity: {"color": "red_4794"}},
// { score: 0.07794742286205292, id: '43' entity: {"color": "grey_8510"}}
// ]
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "quick_setup",
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
],
"annsField": "vector",
"limit": 3,
"outputFields": ["color"]
}'
# {
# "code": 0,
# "data": [
# {
# "distance": 0.08821295201778412,
# "id": 551,
# "color": "orange_6781"
# },
# {
# "distance": 0.0800950899720192,
# "id": 296,
# "color": "red_4794"
# },
# {
# "distance": 0.07794742286205292,
# "id": 43
# "color": "grey_8510"
# }
# ],
# "topks":[3]
# }
Ordenar los resultados de búsqueda por campos escalaresCompatible with Milvus 3.0.x
Por defecto, Milvus ordena los resultados de búsqueda según su puntuación de similitud con el vector de consulta. Si deseas que las entidades devueltas sigan un orden basado en campos escalares, añade order_by_fields a la solicitud de búsqueda.
Cada elemento de ` order_by_fields ` especifica un campo escalar y una dirección de ordenación. Utilice ` "asc" ` para el orden ascendente o ` "desc" ` para el orden descendente. Si omite ` order`, Milvus ordena el campo en orden ascendente.
El siguiente ejemplo ordena los resultados de la búsqueda por price de menor a mayor. Incluye el campo de ordenación en output_fields si deseas inspeccionar el valor del campo en la respuesta.
res = client.search(
collection_name="product_catalog",
data=query_vectors,
anns_field="embedding",
limit=20,
output_fields=["id", "price", "rating", "category"],
order_by_fields=[
{"field": "price", "order": "asc"}
],
)
// java
// nodejs
// go
# restful
También puedes ordenar por varios campos escalares. Milvus aplica los campos en el orden que especifiques. En el siguiente ejemplo, Milvus ordena los resultados por price en orden ascendente. Para las entidades con el mismo price, Milvus ordena a continuación por rating en orden descendente.
res = client.search(
collection_name="product_catalog",
data=query_vectors,
anns_field="embedding",
limit=20,
output_fields=["id", "price", "rating", "category"],
order_by_fields=[
{"field": "price", "order": "asc"},
{"field": "rating", "order": "desc"},
],
)
// java
// nodejs
// go
# restful
En el caso de entidades con los mismos valores en todos los campos de ordenación especificados, Milvus mantiene el orden original según la puntuación de similitud.
Uso de «Limit» y «Offset»
Es posible que observes que el parámetro « limit » incluido en las solicitudes de búsqueda determina el número de entidades que se incluirán en los resultados de la búsqueda. Este parámetro especifica el número máximo de entidades que se devolverán en una sola búsqueda, y suele denominarse «top-K».
Si deseas realizar consultas paginadas, puedes utilizar un bucle para enviar varias solicitudes de búsqueda, incluyendo los parámetros «Limit» y «Offset» en cada una de ellas. En concreto, puedes establecer el parámetro «Limit» en el número de entidades que deseas incluir en los resultados de la consulta actual, y el «Offset» en el número total de entidades que ya se han devuelto.
La tabla siguiente muestra cómo configurar los parámetros «Limit» y «Offset» para consultas paginadas cuando se devuelven 100 entidades a la vez.
Consultas |
Entidades que se deben devolver por consulta |
Total de entidades ya devueltas |
|---|---|---|
La primera consulta |
100 |
0 |
La segunda consulta |
100 |
100 |
La tercera consulta |
100 |
200 |
La enésima consulta |
100 |
100 × (n-1) |
Ten en cuenta que la suma de limit y offset en una sola búsqueda de ANN debe ser inferior a 16 384.
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
res = client.search(
collection_name="quick_setup",
data=[query_vector],
limit=3, # The number of results to return
search_params={
"metric_type": "IP",
"offset": 10 # The records to skip
}
)
import io.milvus.v2.service.vector.request.SearchReq
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp
FloatVec queryVector = new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f});
SearchReq searchReq = SearchReq.builder()
.collectionName("quick_setup")
.data(Collections.singletonList(queryVector))
.topK(3)
.offset(10)
.build();
SearchResp searchResp = client.search(searchReq);
List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
System.out.println("TopK results:");
for (SearchResp.SearchResult result : results) {
System.out.println(result);
}
}
// Output
// TopK results:
// SearchResp.SearchResult(entity={}, score=0.24120237, id=16)
// SearchResp.SearchResult(entity={}, score=0.22559784, id=9)
// SearchResp.SearchResult(entity={}, score=-0.09906838, id=2)
queryVector := []float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"quick_setup", // collectionName
3, // limit
[]entity.Vector{entity.FloatVector(queryVector)},
).WithConsistencyLevel(entity.ClStrong).
WithANNSField("vector").
WithOffset(10))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
}
// 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,
offset: 10 // The record to skip.
})
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "quick_setup",
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
],
"annsField": "vector",
"limit": 3,
"offset": 10
}'
Establecer temporalmente una zona horaria para una búsqueda
Si tu colección tiene un campo « TIMESTAMPTZ », puedes anular temporalmente la zona horaria predeterminada de la base de datos o de la colección para una única operación configurando el parámetro « timezone » en la llamada de búsqueda. Esto controla cómo se muestran y comparan los valores de « TIMESTAMPTZ » durante la operación.
El valor de ` timezone ` debe ser un identificador de zona horaria válido de la IANA (por ejemplo, `Asia/Shanghai`, `America/Chicago` o ` UTC`). Para obtener más información sobre cómo utilizar el campo ` TIMESTAMPTZ `, consulta el apartado «Campo TIMESTAMPTZ».
El siguiente ejemplo muestra cómo establecer temporalmente una zona horaria para una operación de búsqueda:
res = client.search(
collection_name="quick_setup",
anns_field="vector",
data=[query_vector],
limit=3,
search_params={"metric_type": "IP"},
timezone="America/Havana",
)
// java
// js
// go
# restful
export QUERY_VECTOR='[0.1, 0.2, 0.3, 0.4]'
curl -X POST "http://localhost:19530/v2/vectordb/entities/search" \
-H "Content-Type: application/json" \
-H "Request-Timeout: 10" \
-d '{
"collectionName": "quick_setup",
"annsField": "vector",
"data": ['"$QUERY_VECTOR"'],
"limit": 3,
"searchParams": {
"metric_type": "IP",
"timezone": "America/Havana"
}
}'
Mejora de la búsqueda ANN
AUTOINDEX simplifica considerablemente la curva de aprendizaje de las búsquedas ANN. Sin embargo, es posible que los resultados de la búsqueda no siempre sean correctos a medida que aumenta el «top-K». Al reducir el alcance de la búsqueda, mejorar la relevancia de los resultados y diversificarlos, Milvus ofrece las siguientes mejoras en la búsqueda.
Búsqueda filtrada
Puede incluir condiciones de filtrado en una solicitud de búsqueda para que Milvus aplique un filtrado de metadatos antes de realizar las búsquedas con redes neuronales artificiales (ANN), reduciendo así el alcance de la búsqueda de toda la colección a solo las entidades que cumplan las condiciones de filtrado especificadas.
Para obtener más información sobre el filtrado de metadatos y las condiciones de filtrado, consulte «Búsqueda filtrada», «Explicación del filtrado» y los temas relacionados.
Búsqueda por rango
Se puede mejorar la relevancia de los resultados de búsqueda restringiendo la distancia o la puntuación de las entidades devueltas dentro de un rango específico. En Milvus, una búsqueda por rango consiste en trazar dos círculos concéntricos con el vector de incrustación más similar al vector de la consulta como centro. La solicitud de búsqueda especifica el radio de ambos círculos, y Milvus devuelve todas las incrustaciones vectoriales que se encuentran dentro del círculo exterior, pero no del círculo interior.
Para obtener más información sobre la búsqueda por rango, consulta «Búsqueda por rango».
Búsqueda por agrupación
Si las entidades devueltas tienen el mismo valor en un campo específico, es posible que los resultados de la búsqueda no representen la distribución de todas las representaciones vectoriales en el espacio vectorial. Para diversificar los resultados de la búsqueda, plantéate utilizar la búsqueda por agrupación.
Para obtener más información sobre la búsqueda por agrupación, consulta «Búsqueda por agrupación»,
Búsqueda híbrida
Una colección puede incluir varios campos vectoriales para guardar las representaciones vectoriales generadas mediante diferentes modelos de representación. De este modo, puede utilizar una búsqueda híbrida para reordenar los resultados de búsqueda de estos campos vectoriales, mejorando así la tasa de recuperación.
Para obtener más información sobre la búsqueda híbrida, consulta «Búsqueda híbrida».
Iterador de búsqueda
Una única búsqueda con red neuronal artificial (ANN) devuelve un máximo de 16 384 entidades. Considera la posibilidad de utilizar iteradores de búsqueda si necesitas que se devuelvan más entidades en una sola búsqueda.
Para obtener más información sobre los iteradores de búsqueda, consulta «Iterador de búsqueda».
Búsqueda de texto completo
La búsqueda de texto completo es una función que recupera documentos que contienen términos o frases específicos en conjuntos de datos de texto y, a continuación, clasifica los resultados en función de su relevancia. Esta función supera las limitaciones de la búsqueda semántica, que podría pasar por alto términos precisos, garantizando que recibas los resultados más precisos y contextualmente relevantes. Además, simplifica las búsquedas vectoriales al aceptar entradas de texto sin procesar, convirtiendo automáticamente sus datos de texto en incrustaciones dispersas sin necesidad de generar manualmente incrustaciones vectoriales.
Para obtener más información sobre la búsqueda de texto completo, consulta «Búsqueda de texto completo».
Coincidencia de texto
La coincidencia de palabras clave en Milvus permite la recuperación precisa de documentos basada en términos específicos. Esta función se utiliza principalmente para la búsqueda filtrada con el fin de cumplir condiciones específicas y puede incorporar filtrado escalar para refinar los resultados de la consulta, lo que permite realizar búsquedas de similitud dentro de vectores que cumplan criterios escalares.
Para obtener más información sobre la coincidencia de palabras clave, consulta «Coincidencia de palabras clave».
Uso de la clave de partición
Incluir varios campos escalares en el filtrado de metadatos y utilizar una condición de filtrado bastante compleja puede afectar a la eficiencia de la búsqueda. Una vez que se establece un campo escalar como clave de partición y se utiliza una condición de filtrado que incluye dicha clave en la solicitud de búsqueda, esto puede ayudar a restringir el alcance de la búsqueda a las particiones correspondientes a los valores especificados de la clave de partición.
Para obtener más información sobre la clave de partición, consulte «Uso de la clave de partición».
Utilizar mmap
Para obtener más información sobre la configuración de mmap, consulta «Uso de mmap».
Compactación en clúster
Para obtener más información sobre las compactaciones por clústeres, consulte «Compactación por clústeres».
Uso de la reordenación
Para obtener más información sobre el uso de clasificadores para mejorar la relevancia de los resultados de búsqueda, consulta «Descripción general del clasificador de decaimiento » y «Descripción general del clasificador de modelos».