Correspondência de padrões
Em aplicações de pesquisa baseadas em agentes, a pesquisa vetorial e a correspondência de padrões ao estilo do grep complementam-se frequentemente. A pesquisa vetorial recupera entidades semanticamente relevantes, enquanto a correspondência de padrões restringe esses resultados com base em estruturas exatas de cadeias de caracteres, tais como códigos de erro, prefixos de registos, domínios de e-mail, caminhos de URL ou identificadores.
No Milvus, pode expressar estas restrições de padrões em filtros escalares com LIKE para correspondência simples com caracteres curinga e =~ ou !~ para expressões regulares RE2. Pode combinar estes filtros com query, search ou a pesquisa híbrida.
Esta página descreve a correspondência de padrões em expressões de filtro escalares utilizadas por query, search e pela pesquisa híbrida. Estas expressões avaliam valores de campo e não alteram os tokens produzidos por um analisador. Para filtrar tokens durante a análise de texto, consulte o Filtro do Analisador Regex.
As expressões de correspondência de padrões são escritas no parâmetro « filter ». Por exemplo, a consulta seguinte corresponde a mensagens de registo que contenham um código de erro 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"]
}'
Os exemplos nesta página centram-se na expressão atribuída a « filter ». Pode utilizar a mesma sintaxe de expressão de filtro em operações do Milvus que aceitem um filtro escalar, tais como « query », « search » e a pesquisa híbrida.
Tipos de campo suportados
A correspondência de padrões está disponível para valores de cadeia de caracteres.
| Alvo | LIKE | Regex =~ / !~ | Notas |
|---|---|---|---|
VARCHAR campo | Sim | Sim | Alvo típico para a correspondência de padrões em campos de cadeia de caracteres. |
JSON caminho com tipo de conversão « VARCHAR » | Sim | Sim | O valor do caminho JSON deve ser uma cadeia de caracteres para que haja correspondências positivas. Se criar um índice no caminho JSON para aceleração, defina ` json_cast_type="varchar"`. |
ARRAY<VARCHAR> elemento | Sim | Sim | Corresponde a um elemento específico por índice, como tags[0]. A correspondência de padrões não analisa todos os elementos; aplica-se apenas ao elemento no índice especificado. |
Alvo numérico, booleano, vetorial, « TEXT » ou outro alvo não «VARCHAR » | Não | Não | A correspondência de padrões está disponível apenas para valores « VARCHAR », percursos JSON que se resolvem em cadeias de caracteres ou elementos « ARRAY<VARCHAR> » indexados. |
Escolha LIKE ou regex
Escolha o operador mais simples que expresse o padrão de que necessita.
Se precisar de uma correspondência exata de cadeia de caracteres, recomendamos que utilize « == » em vez da correspondência de padrões. Utilize « LIKE » ou «regex» apenas quando o filtro precisar de corresponder a um padrão.
| Requisito | Operador recomendado | Exemplo | Descrição |
|---|---|---|---|
| Igualdade exata da cadeia de caracteres | == | status == "active" | Correspondência exata da cadeia de caracteres « active ». |
| Correspondência simples de prefixo | LIKE | name LIKE "Prod%" | Corresponde a cadeias que começam por Prod. |
| Correspondência simples de sufixo | LIKE | filename LIKE "%.json" | Corresponde a cadeias de caracteres que terminam em .json. |
| Correspondência simples por «contém» | LIKE | description LIKE "%vector database%" | Corresponde a valores que contenham vector database em qualquer parte da cadeia de caracteres. |
| Correspondência com um código estruturado ou padrão de comprimento fixo | =~ | code =~ "E[0-9]{4}" | Corresponde a cadeias de caracteres que contenham, distinguindo maiúsculas de minúsculas, « E » seguido de quatro dígitos, como « E1001 ». |
| Correspondência de padrões sem distinção entre maiúsculas e minúsculas | =~ com (?i) | message =~ "(?i)error" | Corresponde a error, ERROR ou outras variantes de maiúsculas e minúsculas. |
| Excluir valores que correspondam a um padrão de expressão regular | !~ | message !~ "^DEBUG" | Exclui cadeias de caracteres que comecem por DEBUG. |
Utilize LIKE para uma correspondência simples com caracteres curinga. Utilize expressões regulares quando o padrão necessitar de classes de caracteres, repetições, alternativas como error|failed, âncoras ou correspondência sem distinção entre maiúsculas e minúsculas.
Utilize LIKE
O operador LIKE destina-se à correspondência simples com caracteres curinga em valores de cadeia de caracteres. Suporta apenas os seguintes caracteres curinga:
| Caractere curinga | Descrição |
|---|---|
% | Corresponde a zero ou mais caracteres. |
_ | Corresponde a exatamente um carácter. |
Padrões LIKE comuns
Utilize a posição de % e _ para controlar onde o texto fixo aparece na cadeia correspondente.
| Requisito | Padrão | Exemplo de filtro |
|---|---|---|
| Começa com um prefixo | Prod% | filter = 'name LIKE "Prod%"' |
| Termina com um sufixo | %.json | filter = 'filename LIKE "%.json"' |
| Contém uma subcadeia | %vector% | filter = 'description LIKE "%vector%"' |
| Corresponde a um carácter numa posição fixa | AB_% | filter = 'code LIKE "AB_%"' |
Comportamento de correspondência LIKE
Utilize « LIKE » para correspondências de prefixo, sufixo, «contém» e de um único caractere numa posição fixa. « LIKE » não suporta classes de caracteres como « [0-9] », alternâncias como « error|failed », contagens de repetições como « {4} », âncoras como « ^ » ou « $ », nem sinalizadores de insensibilidade a maiúsculas e minúsculas como « (?i) ». Utilize expressões regulares (regex) para esses padrões.
Utilize == para igualdade exata de cadeias completas. Utilize LIKE apenas quando o filtro necessitar de correspondência com caracteres curinga.
Escapar caracteres curinga num padrão LIKE
Nos padrões LIKE, % corresponde a zero ou mais caracteres e _ corresponde exatamente a um caractere. Para corresponder literalmente a %, _ ou \, escape o caractere com uma barra invertida (\):
name LIKE r"\%"corresponde ao valor literal%.name LIKE r"\_%"corresponde a valores que começam com a barra invertida literal (_).name LIKE r"\\%"corresponde a valores que começam com uma barra invertida literal.
Os literais de cadeia de caracteres «raw», escritos como r"..." ou r'...', mantêm as barras invertidas tal como estão nas expressões de filtro do Milvus. São recomendados para LIKE e padrões de expressões regulares que contenham barras invertidas. Sem uma cadeia de caracteres «raw», os literais de cadeia de caracteres normais continuam a processar sequências de escape antes de o padrão ser avaliado, pelo que podem ser necessárias mais barras invertidas.
Utilize expressões regularesCompatible with Milvus 3.0.x
Utilize filtros de expressões regulares quando o padrão exigir funcionalidades de expressões regulares, tais como classes de caracteres, repetição, alternância, âncoras ou correspondência insensível a maiúsculas e minúsculas. O Milvus aplica uma expressão regular RE2 a um valor de cadeia de caracteres.
O lado direito de =~ ou !~ deve ser um literal de cadeia de caracteres.
| Operador | Significado | Exemplo |
|---|---|---|
=~ | Corresponde a valores que satisfazem o padrão de expressão regular. | filter = 'message =~ "E[0-9]{4}"' |
!~ | Exclui valores que satisfazem o padrão de expressão regular. | filter = 'message !~ "^DEBUG"' |
Utilize literais de cadeia de caracteres «raw»
Recomenda-se a utilização de literais de cadeia de caracteres em formato bruto para padrões de expressões regulares que contenham barras invertidas. Numa cadeia de caracteres em formato bruto, escrita como r"..." ou r'...', as barras invertidas são passadas para o motor de expressões regulares tal como estão. Isto evita a necessidade de escape adicional exigida pelos literais de cadeia de caracteres normais.
Por exemplo:
filter = r'filename =~ r"\.json$"'
String filter = "filename =~ r\"\\.json$\"";
filter := `filename =~ r"\.json$"`
const filter = 'filename =~ r"\\.json$"';
filter='filename =~ r"\.json$"'
Isto corresponde a cadeias que terminam com .json, tais como report.json.
Sem uma string «raw» na expressão do filtro do Milvus, as cadeias de caracteres literais comuns processam sequências de escape antes de o padrão de expressão regular ser avaliado. Os caracteres literais escapados podem, por isso, exigir barras invertidas adicionais na string da linguagem anfitriã.
Padrões comuns de expressões regulares
Os exemplos seguintes utilizam sintaxe RE2 comum nas expressões de filtro do Milvus. Para obter a sintaxe completa de expressões regulares, consulte a referência de sintaxe RE2.
| Requisito | Padrão | Exemplo de filtro |
|---|---|---|
| Contém texto literal | error | filter = 'message =~ "error"' |
| Começa com um prefixo | ^ERR | filter = 'code =~ "^ERR"' |
| Termina com um sufixo | \.json$ | filter = 'filename =~ "\\.json$"' |
| Corresponde a uma sequência de dígitos | [0-9]+ | filter = 'message =~ "[0-9]+"' |
| Corresponde a um número fixo de dígitos | [0-9]{4} | filter = 'code =~ "[0-9]{4}"' |
| Corresponde a um domínio de e-mail | @example\.com$ | filter = 'email =~ "@example\\.com$"' |
| Corresponde sem distinguir maiúsculas de minúsculas | (?i)error | filter = 'message =~ "(?i)error"' |
| Corresponde à sequência completa | ^prod-[0-9]+$ | filter = 'name =~ "^prod-[0-9]+$"' |
Para corresponder a uma de várias palavras, utilize a alternância com « | »:
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"'
Ao corresponder metacaracteres de expressões regulares literalmente, utilize o escape no padrão de expressão regular. Por exemplo, para corresponder a um ponto literal (\. na expressão regular), escreva \\. numa cadeia de código-fonte em Python, Java, Go ou Node.js:
filter = 'email =~ "@gmail\\.com$"'
String filter = "email =~ \"@gmail\\.com$\"";
filter := `email =~ "@gmail\\.com$"`
const filter = 'email =~ "@gmail\\.com$"';
filter='email =~ "@gmail\\.com$"'
Nota: Os filtros de expressões regulares do Milvus seguem a sintaxe RE2. Se um padrão de expressão regular utilizar sintaxe que o RE2 não suporta ou for inválido por qualquer outro motivo, o Milvus rejeita a expressão do filtro. Para obter detalhes sobre metacaracteres de expressões regulares, flags e comportamento de correspondência, consulte a referência de sintaxe RE2.
Comportamento de correspondência
Correspondência de subcadeias
A correspondência de expressões regulares do Milvus utiliza a semântica de subcadeias. O padrão não precisa de corresponder ao valor completo do campo. Por exemplo, o filtro seguinte corresponde tanto a E1001 como a 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}"'
Para corresponder ao valor completo do campo, utilize as âncoras ^ e $:
# 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}$"'
Campos VARCHAR que podem ser nulos
Os filtros de expressões regulares não correspondem a valores nulos. Isto aplica-se tanto a « =~ » como a « !~ ». Se pretender excluir um padrão de expressão regular, mas manter os valores nulos, adicione explicitamente « 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'
Caminhos JSON
No caso dos caminhos JSON, os filtros de expressões regulares comportam-se de forma diferente quando o caminho está em falta, é nulo ou resulta num valor que não seja uma cadeia de caracteres:
| Filtro | Inclui valores ausentes/nulos/que não sejam cadeias de caracteres? | Notas |
|---|---|---|
json_field["path"] =~ "pattern" | Não | Corresponde apenas a valores de cadeia de caracteres que satisfaçam o padrão de expressão regular. |
json_field["path"] !~ "pattern" | Sim | Devolve entidades cujo caminho está em falta, é nulo, não é uma cadeia de caracteres ou é uma cadeia de caracteres que não corresponde ao padrão de expressão regular. |
Acelerar a correspondência de padrões com índices
O Milvus suporta vários tipos de índices em campos de cadeia de caracteres que podem ser utilizados em conjunto com filtros « LIKE » e de expressões regulares em campos « VARCHAR » ou percursos de cadeias de caracteres JSON, tais como « NGRAM », « STL_SORT », « INVERTED » e « BITMAP ». A correspondência de padrões pode funcionar sem um índice, mas um índice pode melhorar o desempenho em conjuntos de dados de grande dimensão.
A eficácia do índice depende da expressão do padrão, da capacidade do Milvus para extrair subcadeias literais fixas, bem como da cardinalidade e da distribuição do campo de destino. Padrões do tipo prefixo, como name LIKE "Prod%", podem beneficiar de estratégias de indexação diferentes das utilizadas para padrões do tipo infixo ou sufixo, como description LIKE "%vector%" ou filename LIKE "%.json".
Utilize a tabela seguinte como ponto de partida e, em seguida, realize testes de desempenho com a sua própria carga de trabalho:
| Padrão ou característica dos dados | Índice a considerar | Notas |
|---|---|---|
Contém subcadeias literais fixas, como message =~ "error.*timeout" ou message LIKE "%database%" | NGRAM | É útil quando o Milvus consegue extrair subcadeias literais significativas do padrão. Para mais detalhes, consulte NGRAM. |
| Filtros de cadeias de caracteres do tipo prefixo, exato ou de igualdade, especialmente em campos com cardinalidade baixa a moderada | STL_SORT, INVERTED ou BITMAP | Podem ser mais eficazes quando o campo contém valores repetidos ou quando o filtro se aproxima de uma correspondência exata. Para mais detalhes, consulte STL_SORT, INVERTED e BITMAP. |
| Padrões Regex sem literais fixos, ou padrões dominados por classes de caracteres, tokens curtos ou curingas | Faça testes de desempenho antes de contar com a aceleração por índice | Estes padrões podem proporcionar uma seletividade de índice limitada e podem recorrer a varreduras mais abrangentes. |