Pesquisa por intervalo com StructArray

Utilize esta página para efetuar uma pesquisa por intervalo nos subcampos vetoriais do StructArray. A pesquisa por intervalo devolve resultados vetoriais cuja pontuação ou distância se situa dentro de um limite especificado. Para campos StructArray, utilize a pesquisa por intervalo com pesquisa vetorial ao nível do elemento, em que cada elemento Struct é pesquisado de forma independente.

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 ». O subcampo vetorial « chunks[emb] » está indexado para pesquisa ao nível do elemento com uma métrica vetorial regular, tal como « COSINE », « IP » ou « L2 ».

Como a pesquisa por intervalo se aplica ao StructArray

Modo de pesquisaComportamento da pesquisa por intervaloGranularidade dos resultados
Pesquisa EmbeddingListNão suportado.Não aplicável.
Pesquisa ao nível do elementoUtilize uma consulta vetorial normal com ` radius ` e, opcionalmente, ` range_filter`.Nível de elemento da estrutura.
Pesquisa híbridaSuportada quando o pedido StructArray tem como alvo um campo vetorial ao nível do elemento. Os pedidos ao nível de EmbeddingList não suportam a pesquisa por intervalo.Subpesquisa ao nível do elemento, seguida de reclassificação híbrida.

Se precisar apenas dos elementos Struct mais próximos, comece com a Pesquisa Vetorial Básica com StructArray. Utilize a pesquisa por intervalo quando o resultado tiver de satisfazer um limite de pontuação ou distância, em vez de apenas uma classificação dos K melhores.

Antes de começar

Prepare a coleção, os dados e os índices antes de executar a pesquisa por intervalo.

RequisitoDetalhes
Campo StructArrayA coleção contém um campo StructArray, como, por exemplo, chunks.
Subcampo vetorial ao nível do elementoO subcampo vetorial de destino é chunks[emb], e não chunks[emb_list_vector].
Métrica de indexaçãoO subcampo vetorial é indexado com uma métrica vetorial regular, como COSINE, IP ou L2.
Dados da consultaA consulta é um vetor normal, não um EmbeddingList.

Para a configuração do índice, consulte «Index StructArray Fields».

Utilize «radius» e «range_filter»

Defina ` radius ` para definir o limite de pesquisa. Defina ` range_filter ` quando também precisar de um limite interno. A direção depende de se é melhor uma distância menor ou uma pontuação de similaridade maior.

Tipo de métricaUma pontuação mais elevada é melhor?Condição de intervalo quando se utiliza « range_filter »
L2Não. Uma distância menor é melhor.range_filter <= distance < radius
IP, COSINESim. Quanto maior for a pontuação, melhor.radius < distance <= range_filter

Quando apenas « radius » está definido, a pesquisa de intervalo devolve resultados que satisfazem o limite exterior da métrica. Escolha valores de acordo com a escala de pontuação ou distância das suas incorporações.

O exemplo seguinte pesquisa blocos individuais cujos vetores de « chunks[emb] » sejam suficientemente semelhantes ao vetor de consulta. Cada resultado correspondente representa um elemento Struct correspondente.

from pymilvus import MilvusClient

client = MilvusClient(
    uri="http://localhost:19530",
    token="root:Milvus",
)

query_vector = [0.19, 0.24, 0.30, 0.37]

results = client.search(
    collection_name="tech_articles",
    data=[query_vector],
    anns_field="chunks[emb]",
    search_params={
        "params": {
            "radius": 0.80,
            "range_filter": 0.95,
        },
    },
    limit=10,
    output_fields=[
        "doc_id",
        "title",
        "chunks[text]",
        "chunks[section]",
        "chunks[page]",
        "chunks[quality_score]",
    ],
)

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, « COSINE » é uma métrica do tipo «similaridade», pelo que o intervalo de resultados é superior a radius e inferior ou igual a range_filter. O valor « offset » identifica o elemento «Struct» correspondente na matriz « chunks » quando devolvido.

Adicionar filtros escalares

Pode combinar a pesquisa de intervalo ao nível do elemento com a filtragem escalar do StructArray. Utilize um predicado de nível superior para os campos da entidade pai e utilize element_filter para restringir quais os elementos Struct que participam na pesquisa de intervalo vetorial.

filter_expr = (
    'category == "search" && '
    'element_filter(chunks, '
    '$[section] == "index" && '
    '$[quality_score] > 0.9)'
)

results = client.search(
    collection_name="tech_articles",
    data=[query_vector],
    anns_field="chunks[emb]",
    search_params={
        "params": {
            "radius": 0.80,
            "range_filter": 0.95,
        },
    },
    filter=filter_expr,
    limit=10,
    output_fields=[
        "doc_id",
        "title",
        "category",
        "chunks[text]",
        "chunks[section]",
        "chunks[quality_score]",
    ],
)

O predicado de nível superior seleciona as entidades candidatas. O predicado « element_filter » restringe a pesquisa de intervalo vetorial aos elementos Struct correspondentes. Para mais exemplos de filtragem, consulte «Pesquisa filtrada com StructArray».

Os campos vetoriais ao nível do elemento do StructArray suportam a pesquisa por intervalo na pesquisa híbrida. Adicione « radius » e, opcionalmente, « range_filter » à « AnnSearchRequest » que tem como alvo o campo vetorial ao nível do elemento do StructArray.

from pymilvus import AnnSearchRequest, RRFRanker

title_req = AnnSearchRequest(
    data=[query_vector],
    anns_field="title_vector",
    limit=10,
)

chunk_req = AnnSearchRequest(
    data=[query_vector],
    anns_field="chunks[emb]",
    param={
        "params": {
            "radius": 0.80,
            "range_filter": 0.95,
        },
    },
    limit=10,
    expr='element_filter(chunks, $[section] == "index")',
)

results = client.hybrid_search(
    collection_name="tech_articles",
    reqs=[title_req, chunk_req],
    ranker=RRFRanker(),
    limit=5,
    output_fields=[
        "doc_id",
        "title",
        "chunks[text]",
        "chunks[section]",
        "chunks[quality_score]",
    ],
)

Neste exemplo, apenas a sub-solicitação « chunks[emb] » utiliza parâmetros de pesquisa por intervalo. A solicitação StructArray continua a seguir a semântica ao nível do elemento: o limite do intervalo aplica-se aos resultados do elemento Struct antes de a pesquisa híbrida combinar e reclassificar os resultados.

Interpretar resultados de intervalo

Item de resultadoSignificado
idChave primária da entidade que contém o elemento Struct correspondente.
distance ou pontuaçãoA pontuação ou distância entre o vetor de consulta e o vetor do elemento Struct correspondente.
offsetPosição, com início em zero, do elemento Struct correspondente no campo StructArray quando devolvido.
Chaves primárias repetidasPossível. Mais do que um elemento Struct na mesma entidade pode estar dentro do intervalo especificado.
limitAplica-se a ocorrências de elementos, não a entidades-pai únicas.

Limitações

  • Não utilize uma consulta « EmbeddingList » nem uma métrica « MAX_SIM* » para a pesquisa por intervalo nos subcampos vetoriais do «StructArray». A pesquisa ao nível da «EmbeddingList» não suporta a pesquisa por intervalo.

  • Não combine a pesquisa por intervalo com a pesquisa por agrupamento. Se precisar de um resultado por entidade pai, execute uma pesquisa ao nível do elemento sem parâmetros de intervalo e utilize o agrupamento sempre que for suportado.

  • A pesquisa por intervalo híbrida é suportada para campos vetoriais ao nível do elemento do StructArray. Não é suportada para pedidos do StructArray ao nível da EmbeddingList.

Erros comuns

  • Executar a pesquisa por intervalo em ` chunks[emb_list_vector]`, que se destina à pesquisa ao nível de `EmbeddingList`.

  • Utilizar ` MAX_SIM_COSINE ` em vez de uma métrica normal, como ` COSINE `, para a pesquisa por intervalo ao nível do elemento.

  • Utilizar uma consulta « EmbeddingList » em vez de uma consulta vetorial normal.

  • Esperar que os resultados da pesquisa por intervalo sejam únicos por entidade pai. A pesquisa por intervalo devolve resultados correspondentes a elementos Struct.

  • Utilizar chunks.emb em vez da sintaxe de caminho de subcampo exigida chunks[emb].

Próximos passos

  1. Para conhecer os dois modos básicos de pesquisa vetorial com StructArray, leia «Pesquisa vetorial básica com StructArray».

  2. Para adicionar filtros escalares à pesquisa por intervalo, leia «Pesquisa filtrada com StructArray».

  3. Para devolver, no máximo, um resultado por entidade pai, quando suportado, leia «Pesquisa agrupada com StructArray».

  4. Para verificar os limites de pesquisa específicos de cada versão, leia «Limites do StructArray».