Coincidencia de patrones

En las aplicaciones de búsqueda agentiva, la búsqueda vectorial y la coincidencia de patrones al estilo «grep» suelen complementarse entre sí. La búsqueda vectorial recupera entidades que son semánticamente relevantes, mientras que la coincidencia de patrones filtra esos resultados según estructuras de cadenas exactas, como códigos de error, prefijos de registros, dominios de correo electrónico, rutas de URL o identificadores.

En Milvus, puedes expresar estas restricciones de patrones en filtros escalares con LIKE para la coincidencia simple con comodines, y =~ o !~ para expresiones regulares RE2. Puedes combinar estos filtros con query, search o la búsqueda híbrida.

Esta página describe la coincidencia de patrones en expresiones de filtro escalares utilizadas por query, search y la búsqueda híbrida. Estas expresiones evalúan los valores de los campos y no modifican los tokens generados por un analizador. Para filtrar tokens durante el análisis de texto, consulte el filtro del analizador de expresiones regulares.

Las expresiones de coincidencia de patrones se escriben en el parámetro « filter ». Por ejemplo, la siguiente consulta encuentra mensajes de registro que contienen un código de error como « E1001 »:

from pymilvus import MilvusClient

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

res = client.query(
    collection_name="log_events",
    filter='message =~ "E[0-9]{4}"',
    output_fields=["message", "severity"],
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.QueryReq;
import io.milvus.v2.service.vector.response.QueryResp;
import java.util.Arrays;

MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
        .uri("http://localhost:19530")
        .build());

QueryResp res = client.query(QueryReq.builder()
        .collectionName("log_events")
        .filter("message =~ \"E[0-9]{4}\"")
        .outputFields(Arrays.asList("message", "severity"))
        .build());
import (
    "context"
    "fmt"

    "github.com/milvus-io/milvus/client/v2/milvusclient"
)

ctx := context.Background()
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
    Address: "localhost:19530",
})
if err != nil {
    // handle error
}
defer client.Close(ctx)

res, err := client.Query(ctx, milvusclient.NewQueryOption("log_events").
    WithFilter(`message =~ "E[0-9]{4}"`).
    WithOutputFields("message", "severity"))
if err != nil {
    // handle error
}
fmt.Println(res)
const { MilvusClient } = require('@zilliz/milvus2-sdk-node');

async function main() {
  const client = new MilvusClient({ address: 'http://localhost:19530' });

  const res = await client.query({
    collection_name: 'log_events',
    filter: 'message =~ "E[0-9]{4}"',
    output_fields: ['message', 'severity'],
  });
  console.log(res);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
  --url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
  --header "Authorization: Bearer ${TOKEN}" \
  --header "Content-Type: application/json" \
  --data '{
    "collectionName": "log_events",
    "filter": "message =~ \"E[0-9]{4}\"",
    "outputFields": ["message", "severity"]
  }'
#include "milvus/MilvusClientV2.h"
#include <iostream>

auto client = milvus::MilvusClientV2::Create();

milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

auto request = milvus::QueryRequest()
                   .WithCollectionName("log_events")
                   .WithFilter(R"(message =~ "E[0-9]{4}")")
                   .AddOutputField("message")
                   .AddOutputField("severity");

milvus::QueryResponse response;
status = client->Query(request, response);
if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

Los ejemplos de esta página se centran en la expresión asignada a « filter ». Puede utilizar la misma sintaxis de expresión de filtro en operaciones de Milvus que acepten un filtro escalar, como « query », « search » y la búsqueda híbrida.

Tipos de campo admitidos

La coincidencia de patrones está disponible para valores de cadena.

ObjetivoLIKEExpresión regular =~ / !~Notas
VARCHAR campoSíSíObjetivo típico para la coincidencia de patrones en campos de cadena.
JSON ruta con tipo de conversión « VARCHAR »SíSíEl valor de la ruta JSON debe ser una cadena para que las coincidencias sean positivas. Si creas un índice en la ruta JSON para acelerar el proceso, establece json_cast_type="varchar".
ARRAY<VARCHAR> elementoSíSíCoincide con un elemento específico por índice, como tags[0]. La coincidencia de patrones no analiza todos los elementos; solo se aplica al elemento del índice especificado.
Números, valores booleanos, vectores, TEXT u otros objetivos que no sean de tipo «VARCHAR »NoNoLa coincidencia de patrones solo está disponible para valores de tipo « VARCHAR », rutas JSON que se resuelven en cadenas o elementos indexados de tipo « ARRAY<VARCHAR> ».

Elige «LIKE» o una expresión regular

Elige el operador más sencillo que exprese el patrón que necesitas.

Si necesitas una coincidencia exacta de cadena, te recomendamos que utilices « == » en lugar de la coincidencia de patrones. Utiliza « LIKE » o expresiones regulares solo cuando el filtro tenga que coincidir con un patrón.

RequisitoOperador recomendadoEjemploDescripción
Igualdad exacta de la cadena==status == "active"Coincidencia exacta de la cadena « active ».
Coincidencia simple de prefijoLIKEname LIKE "Prod%"Coincide con cadenas que empiezan por « Prod ».
Coincidencia simple de sufijoLIKEfilename LIKE "%.json"Coincide con cadenas que terminan en « .json ».
Coincidencia simple «contiene»LIKEdescription LIKE "%vector database%"Coincide con valores que contengan « vector database » en cualquier parte de la cadena.
Coincidencia con un código estructurado o un patrón de longitud fija=~code =~ "E[0-9]{4}"Coincide con cadenas que, distinguiendo entre mayúsculas y minúsculas, contengan « E » seguido de cuatro dígitos, como « E1001 ».
Coincidencia de patrones sin distinción entre mayúsculas y minúsculas=~ con (?i)message =~ "(?i)error"Coincide con error, ERROR u otras variantes con mayúsculas o minúsculas.
Excluir valores que coincidan con un patrón de expresión regular!~message !~ "^DEBUG"Excluye las cadenas que empiezan por DEBUG.

Utiliza « LIKE » para una coincidencia sencilla con comodines. Utiliza expresiones regulares cuando el patrón requiera clases de caracteres, repeticiones, alternativas como « error|failed », anclajes o coincidencias que no distingan entre mayúsculas y minúsculas.

Utilizar LIKE

El operador LIKE sirve para la coincidencia simple con comodines en valores de cadena. Solo admite los siguientes comodines:

Carácter comodínDescripción
%Coincide con cero o más caracteres.
_Coincide con exactamente un carácter.

Patrones LIKE habituales

Utiliza la posición de % y _ para controlar dónde aparece el texto fijo en la cadena coincidente.

RequisitoPatrónEjemplo de filtro
Empieza con un prefijoProd%filter = 'name LIKE "Prod%"'
Termina con un sufijo%.jsonfilter = 'filename LIKE "%.json"'
Contiene una subcadena%vector%filter = 'description LIKE "%vector%"'
Coincide con un carácter en una posición fijaAB_%filter = 'code LIKE "AB_%"'

Comportamiento de coincidencia «LIKE»

Utiliza « LIKE » para coincidencias de prefijo, sufijo, contenido y un solo carácter en una posición fija. « LIKE » no admite clases de caracteres como « [0-9] », alternancias como « error|failed », recuentos de repeticiones como « {4} », anclajes como « ^ » o « $ », ni indicadores de no distinción entre mayúsculas y minúsculas como « (?i) ». Utiliza expresiones regulares para esos patrones.

Utiliza « == » para la igualdad exacta de una cadena completa. Utiliza « LIKE » solo cuando el filtro requiera una coincidencia con comodines.

Escapar los comodines en un patrón LIKE

En los patrones LIKE, % coincide con cero o más caracteres y _ coincide exactamente con un carácter. Para que %, _ o \ coincidan literalmente, escapa el carácter con una barra invertida (\):

  • name LIKE r"\%" coincide con el valor literal %.
  • name LIKE r"\_%" coincide con valores que empiezan por el carácter literal « _ ».
  • name LIKE r"\\%" coincide con valores que empiezan por una barra invertida literal.

Los literales de cadena sin procesar, escritos como r"..." o r'...', conservan las barras invertidas tal cual en las expresiones de filtro de Milvus. Se recomiendan para LIKE y patrones de expresiones regulares que contengan barras invertidas. Sin una cadena sin procesar, los literales de cadena normales siguen procesando las secuencias de escape antes de que se evalúe el patrón, por lo que pueden ser necesarias más barras invertidas.

Utiliza expresiones regularesCompatible with Milvus 3.0.x

Utilice filtros de expresiones regulares cuando el patrón requiera características de expresiones regulares, como clases de caracteres, repetición, alternancia, anclajes o coincidencia sin distinción entre mayúsculas y minúsculas. Milvus aplica una expresión regular RE2 a un valor de cadena.

El lado derecho de « =~ » o « !~ » debe ser un literal de cadena.

OperadorSignificadoEjemplo
=~Coincide con los valores que satisfacen el patrón de expresión regular.filter = 'message =~ "E[0-9]{4}"'
!~Excluye los valores que cumplen el patrón de expresión regular.filter = 'message !~ "^DEBUG"'

Utiliza literales de cadena sin formato

Se recomienda el uso de literales de cadena sin escapar para patrones de expresiones regulares que contengan barras invertidas. En una cadena sin escapar, escrita como r"..." o r'...', las barras invertidas se pasan al motor de expresiones regulares tal cual. Esto evita el escape adicional que requieren los literales de cadena normales.

Por ejemplo:

filter = r'filename =~ r"\.json$"'
String filter = "filename =~ r\"\\.json$\"";
filter := `filename =~ r"\.json$"`
const filter = 'filename =~ r"\\.json$"';
filter='filename =~ r"\.json$"'
std::string filter = R"(filename =~ r"\.json$")";

Esto coincide con cadenas que terminan en .json, como report.json.

Sin una cadena sin formato en la expresión del filtro de Milvus, las cadenas literales normales procesan las secuencias de escape antes de que se evalúe el patrón de expresión regular. Por lo tanto, los caracteres literales escapados pueden requerir barras invertidas adicionales en la cadena del lenguaje de host.

Patrones de expresiones regulares comunes

Los siguientes ejemplos utilizan la sintaxis RE2 habitual en las expresiones de filtro de Milvus. Para consultar la sintaxis completa de expresiones regulares, véase la referencia de sintaxis RE2.

RequisitoPatrónEjemplo de filtro
Contiene texto literalerrorfilter = 'message =~ "error"'
Empieza por un prefijo^ERRfilter = 'code =~ "^ERR"'
Termina con un sufijo\.json$filter = 'filename =~ "\\.json$"'
Coincide con una secuencia de dígitos[0-9]+filter = 'message =~ "[0-9]+"'
Coincide con un número fijo de dígitos[0-9]{4}filter = 'code =~ "[0-9]{4}"'
Coincide con un dominio de correo electrónico@example\.com$filter = 'email =~ "@example\\.com$"'
Coincide sin distinguir entre mayúsculas y minúsculas(?i)errorfilter = 'message =~ "(?i)error"'
Coincide con la cadena completa^prod-[0-9]+$filter = 'name =~ "^prod-[0-9]+$"'

Para buscar una de varias palabras, utiliza la alternancia con « | »:

filter = 'message =~ "error|failed|timeout"'
String filter = "message =~ \"error|failed|timeout\"";
filter := `message =~ "error|failed|timeout"`
const filter = 'message =~ "error|failed|timeout"';
filter='message =~ "error|failed|timeout"'
std::string filter = R"(message =~ "error|failed|timeout")";

Al buscar metacaracteres de expresiones regulares de forma literal, escápalos en el patrón de expresión regular. Por ejemplo, para buscar un punto literal (\. en una expresión regular), escribe \\. en una cadena de código fuente de Python, Java, Go o Node.js:

filter = 'email =~ "@gmail\\.com$"'
String filter = "email =~ \"@gmail\\.com$\"";
filter := `email =~ "@gmail\\.com$"`
const filter = 'email =~ "@gmail\\.com$"';
filter='email =~ "@gmail\\.com$"'
std::string filter = R"(email =~ "@gmail\\.com$")";

Nota: Los filtros de expresiones regulares de Milvus siguen la sintaxis RE2. Si un patrón de expresión regular utiliza una sintaxis que RE2 no admite o que no es válida por cualquier otro motivo, Milvus rechaza la expresión del filtro. Para obtener más detalles sobre los metacaracteres de las expresiones regulares, los indicadores y el comportamiento de coincidencia, consulta la referencia de sintaxis de RE2.

Comportamiento de coincidencia

Coincidencia de subcadenas

La coincidencia de expresiones regulares de Milvus utiliza la semántica de subcadenas. No es necesario que el patrón coincida con el valor completo del campo. Por ejemplo, el siguiente filtro coincide tanto con E1001 como con failed with E1001 after retry:

filter = 'message =~ "E[0-9]{4}"'
String filter = "message =~ \"E[0-9]{4}\"";
filter := `message =~ "E[0-9]{4}"`
const filter = 'message =~ "E[0-9]{4}"';
filter='message =~ "E[0-9]{4}"'
std::string filter = R"(message =~ "E[0-9]{4}")";

Para coincidir con el valor completo del campo, utiliza los anclajes ^ y $:

# Match only values that are exactly E followed by four digits
filter = 'code =~ "^E[0-9]{4}$"'
// Match only values that are exactly E followed by four digits
String filter = "code =~ \"^E[0-9]{4}$\"";
// Match only values that are exactly E followed by four digits
filter := `code =~ "^E[0-9]{4}$"`
// Match only values that are exactly E followed by four digits
const filter = 'code =~ "^E[0-9]{4}$"';
# Match only values that are exactly E followed by four digits
filter='code =~ "^E[0-9]{4}$"'
std::string filter = R"(code =~ "^E[0-9]{4}$")";

Campos VARCHAR que admiten valores nulos

Los filtros de expresiones regulares no coinciden con valores nulos. Esto se aplica tanto a « =~ » como a « !~ ». Si deseas excluir un patrón de expresión regular pero conservar los valores nulos, añade explícitamente « OR field IS NULL »:

filter = 'message !~ "^DEBUG" OR message IS NULL'
String filter = "message !~ \"^DEBUG\" OR message IS NULL";
filter := `message !~ "^DEBUG" OR message IS NULL`
const filter = 'message !~ "^DEBUG" OR message IS NULL';
filter='message !~ "^DEBUG" OR message IS NULL'
std::string filter = R"(message !~ "^DEBUG" OR message IS NULL)";

Rutas JSON

En el caso de las rutas JSON, los filtros de expresiones regulares se comportan de forma diferente cuando la ruta falta, es nula o se resuelve en un valor que no es una cadena:

Filtro¿Incluye valores que faltan, nulos o que no son cadenas?Notas
json_field["path"] =~ "pattern"NoSolo coincide con valores de cadena que satisfacen el patrón de expresión regular.
json_field["path"] !~ "pattern"SíDevuelve entidades en las que la ruta falta, es nula, no es una cadena o es una cadena que no coincide con el patrón de expresión regular.

Acelera la coincidencia de patrones con índices

Milvus admite varios tipos de índices en campos de cadena que pueden utilizarse junto con filtros de « LIKE » y de expresiones regulares en campos « VARCHAR » o rutas de cadena JSON, como NGRAM, STL_SORT, INVERTED y BITMAP. La coincidencia de patrones puede funcionar sin un índice, pero un índice puede mejorar el rendimiento en conjuntos de datos de gran tamaño.

La eficacia del índice depende de la expresión del patrón, de si Milvus puede extraer subcadenas literales fijas, y de la cardinalidad y la distribución del campo de destino. Los patrones de tipo prefijo, como name LIKE "Prod%", pueden beneficiarse de estrategias de indexación diferentes a las de los patrones de tipo infijo o sufijo, como description LIKE "%vector%" o filename LIKE "%.json".

Utilice la siguiente tabla como punto de partida y, a continuación, realice pruebas de rendimiento con su propia carga de trabajo:

Patrón o característica de los datosÍndice a considerarNotas
Contiene subcadenas literales fijas, como message =~ "error.*timeout" o message LIKE "%database%"NGRAMResulta útil cuando Milvus puede extraer subcadenas literales significativas del patrón. Para más detalles, consulta NGRAM.
Filtros de cadenas de tipo prefijo, exactos o de igualdad, especialmente en campos con cardinalidad baja o moderadaSTL_SORT, INVERTED o BITMAPPuede resultar más eficaz cuando el campo tiene valores repetidos o cuando el filtro se aproxima a una coincidencia exacta. Para más detalles, consulta STL_SORT, INVERTED y BITMAP.
Patrones Regex sin literales fijos, o patrones dominados por clases de caracteres, tokens cortos o comodinesRealice pruebas de rendimiento antes de confiar en la aceleración por índiceEstos patrones pueden ofrecer una selectividad de índice limitada y pueden recurrir a exploraciones más amplias.