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:

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

L2

Un valor más pequeño indica una mayor similitud.

[0, ∞)

IP

Un valor mayor indica una mayor similitud.

[-1, 1]

COSINE

Un valor mayor indica una mayor similitud.

[-1, 1]

JACCARD

Un valor menor indica una mayor similitud.

[0, 1]

HAMMING

Un valor menor indica una mayor similitud.

[0, dim(vector)]

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
}'

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"
  }
}'

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».