milvus-logo
LFAI
Home
  • Guía del usuario

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 exactos y contextualmente relevantes. Además, simplifica las búsquedas vectoriales al aceptar la entrada de texto sin formato, convirtiendo automáticamente los datos de texto en incrustaciones dispersas sin necesidad de generar manualmente incrustaciones vectoriales.

Esta función, que utiliza el algoritmo BM25 para la puntuación de la relevancia, es especialmente valiosa en escenarios de generación de recuperación aumentada (RAG), donde da prioridad a los documentos que coinciden estrechamente con términos de búsqueda específicos.

Al integrar la búsqueda de texto completo con la búsqueda de vectores densos basada en la semántica, puede mejorar la precisión y la relevancia de los resultados de búsqueda. Para más información, consulte Búsqueda híbrida.

La búsqueda de texto completo está disponible en Milvus Standalone y Milvus Distributed, pero no en Milvus Lite, aunque está previsto añadirla a Milvus Lite.

Resumen

La búsqueda de texto completo simplifica el proceso de búsqueda basada en texto eliminando la necesidad de incrustación manual. Esta función funciona mediante el siguiente flujo de trabajo.

  1. Entrada de texto: Usted inserta documentos de texto sin procesar o proporciona texto de consulta sin necesidad de incrustación manual.

  2. Análisis del texto: Milvus utiliza un analizador para convertir el texto de entrada en términos individuales susceptibles de búsqueda. Para obtener más información sobre los analizadores, consulte Descripción general del analizador.

  3. Procesamiento de funciones: La función incorporada recibe los términos tokenizados y los convierte en representaciones vectoriales dispersas.

  4. Almacenamiento de colecciones: Milvus almacena estas incrustaciones dispersas en una colección para una recuperación eficiente.

  5. Puntuación BM25: Durante una búsqueda, Milvus aplica el algoritmo BM25 para calcular las puntuaciones de los documentos almacenados y clasifica los resultados coincidentes en función de su relevancia para el texto consultado.

Full text search Búsqueda de texto completo

Para utilizar la búsqueda de texto completo, siga estos pasos principales.

  1. Creeuna colección: Configure una colección con los campos necesarios y defina una función para convertir el texto en bruto en incrustaciones dispersas.

  2. Introduzca los datos: Introduzca los documentos de texto sin formato en la colección.

  3. Realizar búsquedas: Utilice textos de consulta para buscar en su colección y obtener resultados relevantes.

Para habilitar la búsqueda de texto completo, cree una colección con un esquema específico. Este esquema debe incluir tres campos necesarios.

  • El campo primario que identifica de forma exclusiva cada entidad de una colección.

  • Un campo VARCHAR que almacene documentos de texto sin procesar, con el atributo enable_analyzer establecido en True. Esto permite a Milvus tokenizar el texto en términos específicos para el procesamiento de funciones.

  • Un campo SPARSE_FLOAT_VECTOR reservado para almacenar incrustaciones dispersas que Milvus generará automáticamente para el campo VARCHAR.

Definir el esquema de la colección

En primer lugar, cree el esquema y añada los campos necesarios.

from pymilvus import MilvusClient, DataType, Function, FunctionType

client = MilvusClient(uri="http://localhost:19530")

schema = client.create_schema()

schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True, auto_id=True)
schema.add_field(field_name="text", datatype=DataType.VARCHAR, max_length=1000, enable_analyzer=True)
schema.add_field(field_name="sparse", datatype=DataType.SPARSE_FLOAT_VECTOR)

import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;

CreateCollectionReq.CollectionSchema schema = CreateCollectionReq.CollectionSchema.builder()
        .build();
schema.addField(AddFieldReq.builder()
        .fieldName("id")
        .dataType(DataType.Int64)
        .isPrimaryKey(true)
        .autoID(true)
        .build());
schema.addField(AddFieldReq.builder()
        .fieldName("text")
        .dataType(DataType.VarChar)
        .maxLength(1000)
        .enableAnalyzer(true)
        .build());
schema.addField(AddFieldReq.builder()
        .fieldName("sparse")
        .dataType(DataType.SparseFloatVector)
        .build());
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";

const address = "http://localhost:19530";
const token = "root:Milvus";
const client = new MilvusClient({address, token});
const schema = [
  {
    name: "id",
    data_type: DataType.Int64,
    is_primary_key: true,
  },
  {
    name: "text",
    data_type: "VarChar",
    enable_analyzer: true,
    enable_match: true,
    max_length: 1000,
  },
  {
    name: "sparse",
    data_type: DataType.SparseFloatVector,
  },
];


console.log(res.results)
export schema='{
        "autoId": true,
        "enabledDynamicField": false,
        "fields": [
            {
                "fieldName": "id",
                "dataType": "Int64",
                "isPrimary": true
            },
            {
                "fieldName": "text",
                "dataType": "VarChar",
                "elementTypeParams": {
                    "max_length": 1000,
                    "enable_analyzer": true
                }
            },
            {
                "fieldName": "sparse",
                "dataType": "SparseFloatVector"
            }
        ]
    }'

En esta configuración

  • id: sirve como clave primaria y se genera automáticamente con auto_id=True.

  • text: almacena los datos de texto sin procesar para las operaciones de búsqueda de texto completo. El tipo de datos debe ser VARCHAR, ya que VARCHAR es el tipo de datos de cadena de Milvus para el almacenamiento de texto. Establezca enable_analyzer=True para permitir que Milvus tokenice el texto. Por defecto, Milvus utiliza el analizador estándar para el análisis de texto. Para configurar un analizador diferente, consulte Visión general.

  • sparseUn campo vectorial reservado para almacenar incrustaciones dispersas generadas internamente para operaciones de búsqueda de texto completo. El tipo de datos debe ser SPARSE_FLOAT_VECTOR.

Ahora, defina una función que convierta su texto en representaciones vectoriales dispersas y añádala al esquema.

bm25_function = Function(
    name="text_bm25_emb", # Function name
    input_field_names=["text"], # Name of the VARCHAR field containing raw text data
    output_field_names=["sparse"], # Name of the SPARSE_FLOAT_VECTOR field reserved to store generated embeddings
    function_type=FunctionType.BM25,
)

schema.add_function(bm25_function)

import io.milvus.common.clientenum.FunctionType;
import io.milvus.v2.service.collection.request.CreateCollectionReq.Function;

import java.util.*;

schema.addFunction(Function.builder()
        .functionType(FunctionType.BM25)
        .name("text_bm25_emb")
        .inputFieldNames(Collections.singletonList("text"))
        .outputFieldNames(Collections.singletonList("vector"))
        .build());
const functions = [
    {
      name: 'text_bm25_emb',
      description: 'bm25 function',
      type: FunctionType.BM25,
      input_field_names: ['text'],
      output_field_names: ['vector'],
      params: {},
    },
];
export schema='{
        "autoId": true,
        "enabledDynamicField": false,
        "fields": [
            {
                "fieldName": "id",
                "dataType": "Int64",
                "isPrimary": true
            },
            {
                "fieldName": "text",
                "dataType": "VarChar",
                "elementTypeParams": {
                    "max_length": 1000,
                    "enable_analyzer": true
                }
            },
            {
                "fieldName": "sparse",
                "dataType": "SparseFloatVector"
            }
        ],
        "functions": [
            {
                "name": "text_bm25_emb",
                "type": "BM25",
                "inputFieldNames": ["text"],
                "outputFieldNames": ["sparse"],
                "params": {}
            }
        ]
    }'

Parámetro

Descripción

name

El nombre de la función. Esta función convierte el texto sin formato del campo text en vectores de búsqueda que se almacenarán en el campo sparse.

input_field_names

El nombre del campo VARCHAR que requiere la conversión de texto a vectores dispersos. Para FunctionType.BM25, este parámetro sólo acepta un nombre de campo.

output_field_names

El nombre del campo donde se almacenarán los vectores dispersos generados internamente. Para FunctionType.BM25, este parámetro sólo acepta un nombre de campo.

function_type

El tipo de función que se utilizará. Establezca el valor en FunctionType.BM25.

Para colecciones con múltiples campos VARCHAR que requieran conversión de texto a vectores dispersos, añada funciones separadas al esquema de la colección, asegurándose de que cada función tiene un nombre y un valor output_field_names únicos.

Configurar el índice

Tras definir el esquema con los campos necesarios y la función incorporada, configure el índice para su colección. Para simplificar este proceso, utilice AUTOINDEX como index_type, una opción que permite a Milvus elegir y configurar el tipo de índice más adecuado en función de la estructura de sus datos.

index_params = client.prepare_index_params()

index_params.add_index(
    field_name="sparse",
    index_type="AUTOINDEX", 
    metric_type="BM25"
)

import io.milvus.v2.common.IndexParam;

List<IndexParam> indexes = new ArrayList<>();
indexes.add(IndexParam.builder()
        .fieldName("sparse")
        .indexType(IndexParam.IndexType.SPARSE_INVERTED_INDEX)
        .metricType(IndexParam.MetricType.BM25)
        .build());
const index_params = [
  {
    field_name: "sparse",
    metric_type: "BM25",
    index_type: "AUTOINDEX",
  },
];
export indexParams='[
        {
            "fieldName": "sparse",
            "metricType": "BM25",
            "indexType": "AUTOINDEX"
        }
    ]'

Parámetro

Descripción

field_name

El nombre del campo vectorial a indexar. Para la búsqueda de texto completo, debe ser el campo que almacena los vectores dispersos generados. En este ejemplo, el valor es sparse.

index_type

El tipo de índice a crear. AUTOINDEX permite a Milvus optimizar automáticamente la configuración del índice. Si necesita más control sobre la configuración del índice, puede elegir entre varios tipos de índice disponibles para vectores dispersos en Milvus. Para más información, consulte Índices soportados en Milvus.

metric_type

El valor de este parámetro debe establecerse en BM25 específicamente para la funcionalidad de búsqueda de texto completo.

Cree la colección

Ahora cree la colección utilizando los parámetros de esquema e índice definidos.

client.create_collection(
    collection_name='demo', 
    schema=schema, 
    index_params=index_params
)

import io.milvus.v2.service.collection.request.CreateCollectionReq;

CreateCollectionReq requestCreate = CreateCollectionReq.builder()
        .collectionName("demo")
        .collectionSchema(schema)
        .indexParams(indexes)
        .build();
client.createCollection(requestCreate);
await client.create_collection(
    collection_name: 'demo', 
    schema: schema, 
    index_params: index_params,
    functions: functions
);
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
    \"collectionName\": \"demo\",
    \"schema\": $schema,
    \"indexParams\": $indexParams
}"

Insertar datos de texto

Después de configurar la colección y el índice, estás listo para insertar datos de texto. En este proceso, sólo necesitas proporcionar el texto en bruto. La función incorporada que definimos anteriormente genera automáticamente el vector disperso correspondiente para cada entrada de texto.

client.insert('demo', [
    {'text': 'information retrieval is a field of study.'},
    {'text': 'information retrieval focuses on finding relevant information in large datasets.'},
    {'text': 'data mining and information retrieval overlap in research.'},
])

import com.google.gson.Gson;
import com.google.gson.JsonObject;

import io.milvus.v2.service.vector.request.InsertReq;

Gson gson = new Gson();
List<JsonObject> rows = Arrays.asList(
        gson.fromJson("{\"text\": \"information retrieval is a field of study.\"}", JsonObject.class),
        gson.fromJson("{\"text\": \"information retrieval focuses on finding relevant information in large datasets.\"}", JsonObject.class),
        gson.fromJson("{\"text\": \"data mining and information retrieval overlap in research.\"}", JsonObject.class)
);

client.insert(InsertReq.builder()
        .collectionName("demo")
        .data(rows)
        .build());
await client.insert({
collection_name: 'demo', 
data: [
    {'text': 'information retrieval is a field of study.'},
    {'text': 'information retrieval focuses on finding relevant information in large datasets.'},
    {'text': 'data mining and information retrieval overlap in research.'},
]);
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "data": [
        {"text": "information retrieval is a field of study."},
        {"text": "information retrieval focuses on finding relevant information in large datasets."},
        {"text": "data mining and information retrieval overlap in research."}       
    ],
    "collectionName": "demo"
}'

Una vez que haya insertado datos en su colección, puede realizar búsquedas de texto completo utilizando consultas de texto sin procesar. Milvus convierte automáticamente su consulta en un vector disperso y clasifica los resultados de búsqueda coincidentes utilizando el algoritmo BM25, y luego devuelve los resultados topK (limit).

search_params = {
    'params': {'drop_ratio_search': 0.2},
}

client.search(
    collection_name='demo', 
    data=['whats the focus of information retrieval?'],
    anns_field='sparse',
    limit=3,
    search_params=search_params
)

import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.response.SearchResp;

Map<String,Object> searchParams = new HashMap<>();
searchParams.put("drop_ratio_search", 0.2);
SearchResp searchResp = client.search(SearchReq.builder()
        .collectionName("demo")
        .data(Collections.singletonList(new EmbeddedText("whats the focus of information retrieval?")))
        .annsField("sparse")
        .topK(3)
        .searchParams(searchParams)
        .outputFields(Collections.singletonList("text"))
        .build());
await client.search(
    collection_name: 'demo', 
    data: ['whats the focus of information retrieval?'],
    anns_field: 'sparse',
    limit: 3,
    params: {'drop_ratio_search': 0.2},
)
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--data-raw '{
    "collectionName": "demo",
    "data": [
        "whats the focus of information retrieval?"
    ],
    "annsField": "sparse",
    "limit": 3,
    "outputFields": [
        "text"
    ],
    "searchParams":{
        "params":{
            "drop_ratio_search":0.2
        }
    }
}'

Parámetro

Descripción

search_params

Diccionario que contiene los parámetros de búsqueda.

params.drop_ratio_search

Proporción de términos de baja frecuencia que se ignoran durante la búsqueda. Para más detalles, consulte Vector disperso.

data

El texto en bruto de la consulta.

anns_field

El nombre del campo que contiene los vectores dispersos generados internamente.

limit

Número máximo de primeras coincidencias a devolver.

Traducido porDeepL

Try Managed Milvus for Free

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

Get Started
Feedback

¿Fue útil esta página?