StructArray를 사용한 필터링 검색

이 페이지를 사용하여 StructArray 필드에 대한 벡터 검색에 스칼라 필터링을 추가할 수 있습니다. StructArray 필터링에는 두 가지 수준이 있습니다. 행 수준 필터는 상위 엔티티를 선택하고, 요소 수준 필터는 요소 수준 벡터 검색에 포함될 Struct 요소를 제한합니다.

이 페이지에서는 ‘StructArray 필드 생성’의 tech_articles 컬렉션을 사용합니다. 이 컬렉션에는 chunks 라는 StructArray 필드가 있으며, section, page, quality_score, has_code 와 같은 스칼라 하위 필드와 검색용 벡터 하위 필드가 포함되어 있습니다.

필터 유형 선택

목표사용결과 동작
category 와 같은 최상위 스칼라 필드를 기준으로 필터링합니다.일반 필터 표현식.검색 전이나 검색 중에 상위 엔티티를 선택합니다.
요소 수준 벡터 검색을 스칼라 조건에 일치하는 Struct 요소로 제한합니다.element_filter.일치하는 Struct 요소만 검색하며, 일치하는 요소의 오프셋을 반환할 수 있습니다.
Struct 요소 중 일부, 전체 또는 특정 개수가 술어와 일치하는지 여부에 따라 엔티티를 선택합니다.MATCH_ANY, MATCH_ALL, MATCH_LEAST, MATCH_MOST 또는 MATCH_EXACT.행 수준 필터링. 이 연산자들은 자체적으로 오프셋을 반환하지 않습니다.

이 페이지에서는 검색 워크플로우에서 StructArray 필터를 사용하는 방법을 설명합니다. 전체 구문 규칙, 지원되는 술어 유형 및 지원되지 않는 술어 행렬에 대해서는 StructArray 연산자를 참조하십시오.

최상위 필드별 필터링

조건이 개별 Struct 요소가 아닌 상위 엔티티에 속하는 경우 일반 필터 표현식을 사용합니다. 이는 EmbeddingList 검색과 요소 수준 검색 모두에서 작동합니다.

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]",
    ],
)

위의 필터는 최상위 ` category ` 필드가 ` "search"`인 엔티티만 선택합니다. 이 필터는 일치하는 단일 Struct 요소를 식별하지 않습니다.

스칼라 조건이 요소 수준 벡터 검색에 참여하는 동일한 Struct 요소에 적용되어야 할 때는 ` element_filter(structArrayField, predicate) `를 사용하십시오. 술어 내부에서는 ` $[subfield] `를 사용하여 현재 Struct 요소의 스칼라 하위 필드를 참조하십시오.

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"],
        )

이 예제에서 최상위 술어 category == "search" 는 후보 엔티티를 선택하고, element_filtersection, quality_score, has_code 가 모두 동일한 Struct 요소 내에서 일치하는 청크로 요소 수준 벡터 검색을 제한합니다.

경고

최상위 술어와 element_filter 를 결합할 때는 element_filter 를 식의 맨 끝에 배치해야 합니다. 필터 식에는 element_filter 가 하나만 포함될 수 있으며, element_filterMATCH_* 를 다른 StructArray 연산자 안에 중첩할 수 없습니다.

MATCH 연산자를 사용한 엔티티 필터링

필터가 부모 엔티티가 Struct 요소를 기준으로 자격 요건을 충족하는지 여부를 결정해야 할 때는 MATCH_* 연산자를 사용합니다. 이 연산자들은 행 수준 필터로, 엔티티를 선택하지만 자체적으로는 요소 오프셋을 반환하지 않습니다.

연산자다음과 같은 경우에 사용합니다예시
MATCH_ANY적어도 하나의 Struct 요소가 술어를 만족해야 합니다.MATCH_ANY(chunks, $[section] == "index")
MATCH_ALL모든 Struct 요소가 술어를 만족해야 합니다.MATCH_ALL(chunks, $[quality_score] > 0.5)
MATCH_LEASTN 개 이상의 Struct 요소가 술어를 만족해야 합니다.MATCH_LEAST(chunks, $[has_code] == true, threshold=2)
MATCH_MOSTN 개 이하의 Struct 요소가 술어를 만족해야 합니다.MATCH_MOST(chunks, $[section] == "appendix", threshold=1)
MATCH_EXACTN 개의 Struct 요소가 정확히 해당 술어를 만족해야 합니다.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]",
    ],
)

EmbeddingList 검색 결과는 엔티티 수준이므로 여기에서는 ` MATCH_ANY `를 사용합니다. 이 필터는 엔티티 내의 청크 중 적어도 하나가 고품질의 ` "index" ` 청크여야 하지만, 검색 결과 자체는 여전히 상위 엔티티를 나타냅니다.

하이브리드 검색에서는 조건이 적용되어야 하는 위치에 StructArray 필터를 적용하십시오. 최상위 필터는 전체 하이브리드 검색에서 공유될 수 있습니다. element_filter 는 요소 수준 제약 조건이 필요한 StructArray 요소 수준 요청에 첨부되어야 합니다.

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]",
    ],
)

filter 인수는 최상위 엔티티 조건을 적용하는 반면, chunk_req 에 대한 expr 는 StructArray 요소 수준 벡터 요청에만 제약 조건을 적용합니다. 지원되는 하이브리드 검색 조합 및 버전별 제한 사항에 대해서는 ‘StructArray를 사용한 하이브리드 검색’‘StructArray 제한 사항’을 참조하십시오.

술어 지원 요약

StructArray 술어에서 스칼라 하위 필드를 사용하십시오. 벡터 하위 필드는 스칼라 술어 입력으로 사용할 수 없습니다.

서브필드 유형일반적인 술어 예시
BOOL$[has_code] == true, !($[has_code] == true)
정수형$[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%"
벡터 하위 필드$[...] 의 스칼라 술어 입력으로는 지원되지 않습니다. 대신 벡터 검색을 통해 벡터 하위 필드를 사용하십시오.

JSON 경로, 배열 컨테이너 함수, 텍스트 일치 함수, ` $[...]`에 대한 null 술어, 기하 함수, `Timestamptz` 표현식 및 제네릭 함수 호출과 같이 지원되지 않는 사례에 대해서는 StructArray 연산자를 참조하십시오.

흔히 저지르는 실수

  • element_filterMATCH_* 외부에서 $[subfield] 를 사용하는 경우.

  • element_filter(chunks, $[section] == "index") 와 같은 StructArray 연산자 구문 대신 chunks.section 를 사용하는 경우.

  • 행 수준 필터링만 필요한 경우 element_filter 를 사용하는 경우. 엔티티를 선택하기만 하면 되는 경우에는 대신 MATCH_ANY 를 사용하십시오.

  • MATCH_* 가 요소 오프셋을 반환할 것이라고 기대하지 마십시오. 이 연산자들은 엔티티를 선택할 뿐, 그 자체로는 일치하는 단일 요소를 식별하지 않습니다.

  • $[has_code] 와 같은 단순한 부울 술어를 작성하는 경우. $[has_code] == true 와 같은 명시적인 비교 연산자를 사용하십시오.

  • 동일한 필터 표현식 내에서 최상위 술어 앞에 element_filter 를 배치하는 경우.

다음 단계

  1. StructArray 필터 구문의 전체 내용을 확인하려면 StructArray 연산자를 참조하십시오.

  2. 먼저 필터링되지 않은 벡터 검색을 실행하려면 ‘StructArray를 사용한 기본 벡터 검색’을 참조하십시오.

  3. 자주 사용하는 StructArray 필터에 대한 스칼라 인덱스를 생성하려면 StructArray 필드 인덱싱을 참조하십시오.

  4. 버전별 필터 및 검색 제한 사항을 확인하려면 ‘StructArray 제한 사항’을 참조하십시오.

번역DeepL

관리형 Milvus를 무료로 사용해 보세요

Zilliz Cloud는 번거로움이 없으며, Milvus 기반으로 10배 더 빠릅니다.

시작하기
피드백

이 페이지가 도움이 되었나요?