Pesquisa filtrada com StructArray
Utilize esta página para adicionar filtragem escalar à pesquisa vetorial em campos StructArray. A filtragem do StructArray tem dois níveis: os filtros ao nível da linha selecionam entidades pai, enquanto os filtros ao nível do elemento restringem quais os elementos Struct que participam na pesquisa vetorial ao nível do elemento.
Esta página utiliza a coleção « tech_articles » da secção «Criar um campo StructArray». A coleção possui um campo StructArray denominado « chunks », com subcampos escalares como « section », « page », « quality_score » e « has_code », além de subcampos vetoriais para pesquisa.
Escolha um tipo de filtro
| Objetivo | Utilização | Comportamento do resultado |
|---|---|---|
Filtrar por um campo escalar de nível superior, como category. | Expressão de filtro normal. | Seleciona entidades pai antes ou durante a pesquisa. |
| Restringe a pesquisa vetorial ao nível do elemento aos elementos Struct que correspondam às condições escalares. | element_filter. | Pesquisa apenas os elementos Struct correspondentes e pode devolver os deslocamentos dos elementos correspondentes. |
| Seleciona entidades consoante se algum, todos ou um número específico de elementos Struct correspondam a um predicado. | MATCH_ANY, MATCH_ALL, MATCH_LEAST, MATCH_MOST ou MATCH_EXACT. | Filtragem ao nível da linha. Estes operadores não devolvem deslocamentos por si próprios. |
Esta página explica como utilizar filtros StructArray em fluxos de trabalho de pesquisa. Para conhecer as regras sintáticas completas, os tipos de predicados suportados e a matriz de predicados não suportados, consulte Operadores StructArray.
Filtrar por campos de nível superior
Utilize expressões de filtro normais quando a condição pertencer à entidade pai e não a um elemento Struct individual. Isto funciona tanto com a pesquisa EmbeddingList como com a pesquisa ao nível do elemento.
from pymilvus import MilvusClient
from pymilvus.client.embedding_list import EmbeddingList
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus",
)
query = EmbeddingList()
query.add([0.12, 0.21, 0.32, 0.44])
query.add([0.18, 0.23, 0.29, 0.36])
results = client.search(
collection_name="tech_articles",
data=[query],
anns_field="chunks[emb_list_vector]",
filter='category == "search"',
limit=3,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
],
)
O filtro acima seleciona apenas entidades cujo campo de nível superior « category » seja « "search" ». Não identifica um único elemento Struct correspondente.
Filtrar a pesquisa vetorial ao nível do elemento
Utilize « element_filter(structArrayField, predicate) » quando as condições escalares se aplicarem ao mesmo elemento Struct que participa na pesquisa vetorial ao nível do elemento. Dentro do predicado, utilize « $[subfield] » para se referir a subcampos escalares do elemento Struct atual.
query_vector = [0.19, 0.24, 0.30, 0.37]
filter_expr = (
'category == "search" && '
'element_filter(chunks, '
'$[section] == "index" && '
'$[quality_score] > 0.9 && '
'$[has_code] == true)'
)
results = client.search(
collection_name="tech_articles",
data=[query_vector],
anns_field="chunks[emb]",
filter=filter_expr,
limit=5,
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
"chunks[page]",
"chunks[quality_score]",
"chunks[has_code]",
],
)
for hits in results:
for hit in hits:
print(
"doc_id:", hit["id"],
"distance:", hit["distance"],
"offset:", hit.get("offset"),
"entity:", hit["entity"],
)
Neste exemplo, o predicado de nível superior category == "search" seleciona entidades candidatas, e element_filter restringe a pesquisa vetorial ao nível do elemento a blocos em que section, quality_score e has_code coincidem todos no mesmo elemento Struct.
Aviso
Quando combinar um predicado de nível superior com element_filter, coloque element_filter no final da expressão. Uma expressão de filtro só pode conter um element_filter, e não é possível aninhar element_filter ou MATCH_* dentro de outro operador StructArray.
Filtrar entidades com operadores MATCH
Utilize os operadores « MATCH_* » quando o filtro tiver de determinar se uma entidade pai é elegível com base nos seus elementos «Struct». Estes operadores são filtros ao nível da linha: selecionam entidades, mas não devolvem, por si só, os deslocamentos dos elementos.
| Operador | Utilize-o quando | Exemplo |
|---|---|---|
MATCH_ANY | Pelo menos um elemento Struct deve satisfazer o predicado. | MATCH_ANY(chunks, $[section] == "index") |
MATCH_ALL | Todos os elementos Struct devem satisfazer o predicado. | MATCH_ALL(chunks, $[quality_score] > 0.5) |
MATCH_LEAST | Pelo menos N elementos da estrutura devem satisfazer o predicado. | MATCH_LEAST(chunks, $[has_code] == true, threshold=2) |
MATCH_MOST | No máximo, N elementos da Struct devem satisfazer o predicado. | MATCH_MOST(chunks, $[section] == "appendix", threshold=1) |
MATCH_EXACT | Exatamente N elementos Struct devem satisfazer o predicado. | MATCH_EXACT(chunks, $[section] == "summary", threshold=1) |
filter_expr = (
'category == "search" && '
'MATCH_ANY(chunks, $[section] == "index" && $[quality_score] > 0.9)'
)
results = client.search(
collection_name="tech_articles",
data=[query],
anns_field="chunks[emb_list_vector]",
filter=filter_expr,
limit=3,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
Utilize « MATCH_ANY » aqui porque o resultado da pesquisa da EmbeddingList é ao nível da entidade. O filtro exige que, pelo menos, um fragmento na entidade seja um fragmento « "index" » de alta qualidade, mas o próprio resultado da pesquisa continua a representar a entidade pai.
Utilizar filtros na pesquisa híbrida
Na pesquisa híbrida, aplique filtros StructArray onde a condição deva ter efeito. Um filtro de nível superior pode ser partilhado por toda a pesquisa híbrida. Um element_filter deve ser anexado ao pedido ao nível do elemento StructArray que necessite de restrições ao nível do elemento.
from pymilvus import AnnSearchRequest, RRFRanker
query_vector = [0.19, 0.24, 0.30, 0.37]
title_req = AnnSearchRequest(
data=[query_vector],
anns_field="title_vector",
limit=10,
)
chunk_req = AnnSearchRequest(
data=[query_vector],
anns_field="chunks[emb]",
limit=10,
expr='element_filter(chunks, $[section] == "index" && $[quality_score] > 0.9)',
)
results = client.hybrid_search(
collection_name="tech_articles",
reqs=[title_req, chunk_req],
ranker=RRFRanker(),
filter='category == "search"',
limit=5,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
O argumento « filter » aplica a condição da entidade de nível superior, enquanto o « expr » em « chunk_req » restringe apenas a solicitação do vetor ao nível do elemento do StructArray. Para combinações de pesquisa híbrida suportadas e limites específicos da versão, consulte «Pesquisa híbrida com StructArray » e «Limites do StructArray».
Resumo do suporte a predicados
Utilize subcampos escalares nos predicados StructArray. Os subcampos vetoriais não são entradas de predicados escalares.
| Tipo de subcampo | Exemplos típicos de predicados |
|---|---|
BOOL | $[has_code] == true, !($[has_code] == true) |
| Tipos inteiros | $[page] >= 2, $[page] in [1, 2, 3] |
FLOAT, DOUBLE | $[quality_score] > 0.9, 0.7 < $[quality_score] < 0.95 |
VARCHAR | $[section] == "index", $[text] like "range%" |
| Subcampos vetoriais | Não são suportados como entradas de predicados escalares d $[...]. Em vez disso, utilize subcampos vetoriais através da pesquisa vetorial. |
Para casos não suportados, tais como percursos JSON, funções de contentores de matrizes, funções de correspondência de texto, predicados nulos em ` $[...]`, funções de geometria, expressões `Timestamptz` e chamadas a funções genéricas, consulte Operadores StructArray.
Erros comuns
Utilizar `
$[subfield]` fora de `element_filter` ou `MATCH_*`.Utilizar `
chunks.section` em vez da sintaxe do operador `StructArray`, como `element_filter(chunks, $[section] == "index")`.Utilizar `
element_filter` quando apenas é necessária uma filtragem ao nível da linha. Utilize `MATCH_ANY` em vez disso, se apenas precisar de selecionar entidades.Esperar que `
MATCH_*` devolva deslocamentos de elementos. Estes operadores selecionam entidades e não identificam, por si só, um elemento correspondente.Escrever predicados booleanos simples, como
$[has_code]. Utilize comparações explícitas, como$[has_code] == true.Colocar «
element_filter» antes de um predicado de nível superior na mesma expressão de filtro.
Próximos passos
Para rever a sintaxe completa do filtro StructArray, leia Operadores StructArray.
Para executar primeiro pesquisas vetoriais não filtradas, leia «Pesquisa vetorial básica com StructArray».
Para criar índices escalares para filtros StructArray utilizados com frequência, leia «Indexar campos StructArray».
Para verificar os limites de filtragem e pesquisa específicos de cada versão, leia «Limites do StructArray».