ChromaDB 메타데이터 필터링

ChromaDB 메타데이터 필터링 (Metadata Filtering)

벡터만으로 검색하면 "어떤 페이지의, 어떤 장(chapter)에서 온 결과인지" 같은 부가 정보를 걸러내기 어려워요. 그때 메타데이터(metadata) 를 쓰면 돼요. get이나 querywhere 인자를 넘기면 메타데이터 기준으로 결과를 걸러낼 수 있어요.

출처: 공식문서 - Metadata Filtering

where로 필터링하기

예를 들어 page라는 메타데이터 필드 값이 정확히 10인 레코드만 검색하려면 querywhere={"page": 10}을 넘겨요.

collection.query(
    query_texts=["first query", "second query"],
    where={"page": 10}
)

where 딕셔너리 구조는 메타데이터 필드 이름을 키로, 그 값에 연산자와 비교 값을 넣는 형태예요.

{
    "metadata_field": {
        <Operator>: <Value>
    }
}

값 비교 연산자를 쓰려면 $gt, $gte, $lt, $lte 같은 연산자 키를 사용해요. 예를 들어 page가 10보다 큰 레코드를 찾으려면:

collection.query(
    query_texts=["first query", "second query"],
    where={"page": { "$gt": 10 }}
)

논리 연산자 사용하기

여러 조건을 묶을 때는 $and, $or를 써요. 예를 들어 page가 5 이상이고 10 이하인 레코드를 검색하면:

collection.query(
    query_texts=["first query", "second query"],
    where={
        "$and": [
            {"page": {"$gte": 5 }},
            {"page": {"$lte": 10 }},
        ]
    }
)

$or로는 여러 값을 한 번에 매칭할 수 있어요. colorred이거나 blue인 모든 레코드를 가져오려면:

collection.get(
    where={
        "$or": [
            {"color": "red"},
            {"color": "blue"},
        ]
    }
)

배열 메타데이터 다루기

ChromaDB는 메타데이터 필드에 배열(값 목록)도 저장할 수 있어요. 이때 $contains$not_contains 연산자로 배열이 특정 값을 포함하는지 걸러요.

배열 메타데이터를 넣는 예시:

collection.add(
    ids=["m1", "m2", "m3"],
    embeddings=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
    metadatas=[
        {"genres": ["action", "comedy"], "year": 2020},
        {"genres": ["drama"], "year": 2021},
        {"genres": ["action", "thriller"], "year": 2022},
    ],
)

genres 배열이 "action"을 포함하는 레코드를 가져오려면 $contains를 쓰고, 포함하지 않는 레코드를 가져오려면 $not_contains를 써요.

# genres에 "action"이 포함된 레코드 전부
collection.get(
    where={"genres": {"$contains": "action"}}
)

# genres에 "action"이 포함되지 않은 레코드 전부
collection.get(
    where={"genres": {"$not_contains": "action"}}
)

# 정수 배열도 동일하게 동작해요
collection.get(
    where={"scores": {"$contains": 20}}
)

# 다른 필터 조합도 가능해요
collection.get(
    where={
        "$and": [
            {"genres": {"$contains": "action"}},
            {"year": {"$gte": 2021}},
        ]
    }
)

문서 검색과 조합하기

.get.query는 메타데이터 필터링을 문서 검색(document search)과 함께 처리할 수 있어요. where로 메타데이터를, where_document로 본문 텍스트를 필터링하면 돼요.

collection.query(
    query_texts=["doc10", "thus spake zarathustra", ...],
    n_results=10,
    where={"metadata_field": "is_equal_to_this"},
    where_document={"$contains":"search_string"}
)

더 알아보기 (Learn more)

  • 문서 본문 필터링은 전문 검색 (Full-Text Search) 문서를 참고해요.
  • 컬렉션 단위 검색 관련 더 많은 내용은 ChromaDB 공식 Querying Collections 문서를 확인해요.