Búsqueda básica de vectores
Basándose en un archivo de índice que registra el orden de las incrustaciones vectoriales, la búsqueda por vecino más próximo aproximado (RNA) localiza un subconjunto de incrustaciones vectoriales basándose en el vector de consulta incluido en una solicitud de búsqueda recibida, compara el vector de consulta con los del subgrupo y devuelve los resultados más similares. Con la búsqueda ANN, Milvus proporciona una experiencia de búsqueda eficiente. Esta página le ayuda a aprender a realizar búsquedas RNA básicas.
Si añade dinámicamente nuevos campos después de haber creado la colección, las búsquedas que incluyan estos campos devolverán los valores por defecto definidos o NULL para las entidades que no hayan establecido valores explícitamente. Para obtener más información, consulte Añadir campos a una colección existente.
Visión general
La búsqueda RNA y la búsqueda k-Nearest Neighbors (kNN) son los métodos habituales en las búsquedas de similitud vectorial. En una búsqueda kNN, hay que comparar todos los vectores de un espacio vectorial con el vector de consulta que figura en la petición de búsqueda antes de averiguar cuáles son los más similares, lo que lleva mucho tiempo y consume muchos recursos.
A diferencia de las búsquedas kNN, un algoritmo de búsqueda RNA solicita un archivo de índice que registra el orden 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 de vectores 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, clasificar los miembros del grupo en función de la similitud con el vector de consulta y determinar los K miembros principales del grupo.
Las búsquedas RNA dependen de índices preconstruidos, y el rendimiento de la búsqueda, el uso de memoria y la corrección de la búsqueda pueden variar con los tipos de índice que elija. Es necesario equilibrar el rendimiento y la corrección de la búsqueda.
Para reducir la curva de aprendizaje, Milvus proporciona AUTOINDEX. Con AUTOINDEX, Milvus puede analizar la distribución de datos dentro de su colección mientras construye el índice y establece los parámetros de índice más optimizados basándose en el análisis para lograr un equilibrio entre el rendimiento de la búsqueda y la corrección.
En esta sección, encontrará información detallada sobre los siguientes temas:
Búsqueda monovectorial
En las búsquedas RNA, una búsqueda de un solo vector se refiere a una búsqueda que implica sólo un vector de consulta. Basándose en el índice pre-construido y en el tipo de métrica incluido en la petición de búsqueda, Milvus encontrará los K vectores más similares al vector de consulta.
En esta sección, aprenderá a realizar una búsqueda de un solo vector. La petición de búsqueda lleva un único vector de consulta y pide a Milvus que utilice el Producto Interior (PI) para calcular la similitud entre los vectores de consulta y los vectores de la colección y devuelve 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" \
-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 su puntuación de similitud con el vector de consulta en orden descendente. La puntuación de similitud también se denomina distancia al vector de consulta, y sus rangos de valores varían según los tipos de métrica utilizados.
La siguiente tabla enumera los tipos de métrica aplicables y los rangos de distancia correspondientes.
Tipo de métrica |
Características |
Rango de distancia |
|---|---|---|
|
Un valor menor 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 de vectores múltiples
De forma similar, puede incluir múltiples vectores de consulta en una petición de búsqueda. Milvus realizará búsquedas RNA de 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" \
-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 claves primariasCompatible with Milvus 2.6.9+
En lugar de establecer vectores de consulta, puede 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
Búsqueda RNA en partición
Supongamos que ha creado varias particiones en una colección y puede restringir el ámbito de búsqueda a un número específico de particiones. En ese caso, puede incluir los nombres de las particiones de destino en la petición de búsqueda para restringir el ámbito de la búsqueda dentro de 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 asume una partición llamada ParticiónA en tu 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" \
-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]
# }
Utilizar campos de salida
En un resultado de búsqueda, Milvus incluye los valores de campo primario y las distancias/puntuaciones de similitud de las entidades que contienen las incrustaciones vectoriales top-K por defecto. Puede incluir los nombres de los campos de destino, incluyendo tanto los campos vectoriales como escalares, en una petición de búsqueda como campos de salida para hacer que los resultados de la búsqueda lleven los valores de otros campos en 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" \
-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]
# }
Utilizar límite y desplazamiento
Es posible que observe que el parámetro limit incluido en las peticiones 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 a devolver en una única búsqueda, y suele denominarse top-K.
Si desea realizar consultas paginadas, puede utilizar un bucle para enviar múltiples peticiones de búsqueda, con los parámetros Limit y Offset transportados en cada petición de consulta. En concreto, puede establecer el parámetro Límite en el número de entidades que desea incluir en los resultados de la consulta actual, y establecer el Desplazamiento en el número total de entidades que ya se han devuelto.
La siguiente tabla muestra cómo establecer los parámetros Límite y Desplazamiento para consultas paginadas que devuelven 100 entidades cada vez.
Consultas |
Entidades a devolver por consulta |
Entidades ya devueltas en total |
|---|---|---|
1ª consulta |
100 |
0 |
2ª consulta |
100 |
100 |
3ª consulta |
100 |
200 |
Enésima consulta |
100 |
100 x (n-1) |
Tenga en cuenta que, la suma de limit y offset en una sola búsqueda RNA 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" \
-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 su colección tiene un campo TIMESTAMPTZ, puede anular temporalmente la zona horaria predeterminada de la base de datos o de la colección para una sola operación estableciendo 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 IANA válido (por ejemplo, Asia/Shanghai, America/Chicago o UTC). Para obtener más información sobre cómo utilizar un campo TIMESTAMPTZ, consulte 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
Mejora de la búsqueda RNA
AUTOINDEX aplana considerablemente la curva de aprendizaje de las búsquedas RNA. Sin embargo, los resultados de la búsqueda pueden no ser siempre correctos a medida que aumenta el top-K. Al reducir el alcance de la búsqueda, mejorar la relevancia de los resultados de la búsqueda y diversificar los resultados de la búsqueda, Milvus elabora las siguientes mejoras de la búsqueda.
Búsqueda filtrada
Puede incluir condiciones de filtrado en una solicitud de búsqueda para que Milvus realice un filtrado de metadatos antes de realizar búsquedas RNA, reduciendo el ámbito de búsqueda de toda la colección a sólo las entidades que coincidan con 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 temas relacionados.
Búsqueda por rangos
Puede mejorar la relevancia de los resultados de búsqueda restringiendo la distancia o puntuación de las entidades devueltas dentro de un rango específico. En Milvus, una búsqueda por rango implica dibujar dos círculos concéntricos con el vector incrustado más similar al vector de consulta como centro. La petición de búsqueda especifica el radio de ambos círculos, y Milvus devuelve todas las incrustaciones vectoriales que caen dentro del círculo exterior pero no del círculo interior.
Para más información sobre la búsqueda por rango, consulte Búsqueda por rango.
Búsqueda por agrupación
Si las entidades devueltas tienen el mismo valor en un campo específico, los resultados de la búsqueda pueden no representar la distribución de todas las incrustaciones vectoriales en el espacio vectorial. Para diversificar los resultados de la búsqueda, considere la posibilidad de utilizar la búsqueda de agrupación.
Para más información sobre la búsqueda agrupada, consulte Búsqueda agrupada,
Búsqueda híbrida
Una colección puede incluir múltiples campos vectoriales para guardar las incrustaciones vectoriales generadas utilizando diferentes modelos de incrustación. De este modo, puede utilizar una búsqueda híbrida para volver a clasificar los resultados de búsqueda de estos campos vectoriales, mejorando el índice de recuperación.
Para obtener más información sobre la búsqueda híbrida, consulte Búsqueda híbrida.
Iterador de búsqueda
Una única búsqueda RNA devuelve un máximo de 16.384 entidades. Considere el uso de iteradores de búsqueda si necesita devolver más entidades en una sola búsqueda.
Para obtener más información sobre los iteradores de búsqueda, consulte 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 puede pasar por alto términos precisos, garantizando que usted reciba los resultados más precisos y contextualmente relevantes. Además, simplifica las búsquedas vectoriales al aceptar la entrada de texto sin formato, 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, consulte Búsqueda de texto completo.
Coincidencia de texto
La concordancia de palabras clave en Milvus permite una recuperación precisa de documentos basada en términos específicos. Esta función se utiliza principalmente para la búsqueda filtrada para satisfacer condiciones específicas y puede incorporar el filtrado escalar para refinar los resultados de la consulta, permitiendo búsquedas de similitud dentro de vectores que cumplen criterios escalares.
Para obtener más información sobre la concordancia de palabras clave, consulte Concordancia de palabras clave.
Utilizar clave de partición
Involucrar varios campos escalares en el filtrado de metadatos y utilizar una condición de filtrado bastante complicada puede afectar a la eficacia de la búsqueda. Una vez establecido un campo escalar como clave de partición y utilizada una condición de filtrado que incluya la clave de partición en la petición de búsqueda, puede ayudar a restringir el ámbito de búsqueda dentro de las particiones correspondientes a los valores de clave de partición especificados.
Para más detalles sobre la clave de partición, consulte Utilizar clave de partición.
Utilizar mmap
Para más información sobre la configuración mmap, consulte Utilizar mmap.
Compactación en clúster
Para obtener más información sobre la compactación de clústeres, consulte Compactación de clústeres.
Utilizar reranking
Para obtener más información sobre el uso de clasificadores para mejorar la relevancia de los resultados de búsqueda, consulte Decay Ranker Overview y Model Ranker Overview.