조건부 필터
조건부 필터 (Conditional filters)
검색 결과를 어떤 조건으로 걸러낼지 정하는 게 바로 조건부 필터예요. 객체 조회(Object-level), 집계(Aggregate), 배치 삭제 같은 질의에 조건부 필터를 붙일 수 있는데, 여기 쓰이는 연산자를 where 필터라고 불러요. 필터 하나가 조건 하나로 이뤄질 수도 있고, And나 Or로 여러 조건을 묶을 수도 있어요.
단일 조건 (operand)
대수적 조건 하나하나를 "operand"라고 불러요. operand마다 필요한 요소는 세 가지예요.
- 연산자 타입 (operator type)
- 프로퍼티 경로 (property path)
- 값과 값의 타입 (value 및 value type)
예를 들어 아래 필터는 wordCount가 1000보다 큰(GreaterThan) Article 클래스 객체만 허용해요.
# Python 클라이언트 예시 — wordCount가 1000보다 큰 Article만
필터 구조와 동작
Equal 필터의 다중 단어 질의
where 필터에서 Equal 연산자를 다중 단어 프로퍼티에 쓰면 그 동작이 프로퍼티의 토큰화(tokenization) 설정에 따라 달라져요. 사용 가능한 토큰화 종류의 차이는 스키마 프로퍼티 토큰화 섹션을 참고하면 돼요.
Like 필터의 성능
Like 필터는 그 프로퍼티의 역인덱스 전체를 순회해요. 그래서 검색 시간이 데이터셋 크기에 따라 선형적으로 늘어나고, 데이터가 크면 느려질 수 있어요.
Like의 와일드카드 리터럴 매칭
현재 Like 필터는 와일드카드 문자(?, *)를 리터럴 문자로 매칭하지 못해요. 예를 들어 car*에 정확히 매칭하면서 car, care, carpet은 제외하는 식의 검색은 지금은 불가능해요. Weaviate가 알고 있는 알려진 제한 사항이고, 향후 버전에서 해결될 수 있어요.
ContainsAny / ContainsAll / ContainsNone
이 세 연산자는 텍스트를 배열로 취급해요. 텍스트를 선택한 토큰화 방식에 따라 토큰 배열로 쪼갠 뒤, 그 배열을 대상으로 검색을 수행해요.
ContainsAny: 입력 배열의 값 중 하나라도 있는 객체를 반환해요. 예를 들어languages_spoken(text 타입)에 값["Chinese", "French", "English"]로ContainsAny질의를 하면, 그 언어 중 하나라도 말하는 사람이 결과로 나와요.ContainsAll: 값을 전부 포함하는 객체만 반환해요.ContainsNone: 값 중 어느 것도 없는 객체를 반환해요. 스페인어만 말하는 사람이languages_spoken에["Chinese", "French", "English"]로ContainsNone질의를 하면 결과에 포함되는 식이에요.
주의할 점이 있어요. REST API로 배치 삭제에 이 연산자들을 쓸 때는 프로퍼티 데이터 타입에 맞는 배열 접미사 인자(valueTextArray, valueIntArray 등)로 값을 지정해야 해요. 검색에서 쓰는 단일 인자(valueText, valueInt)와는 달라요.
또 geo 좌표와 전화번호 프로퍼티는 이 연산자들을 지원하지 않아요. geo 필터링은 WithinGeoRange를 써야 해요.
필터 성능 개선
가끔 필터 아키텍처와 데이터 구조가 어긋나서 필터 성능이 느려질 수 있어요. 예를 들어 프로퍼티의 카디널리티(고유 값 개수)가 매우 크면 범위 기반 필터가 느려질 수 있어요.
필터 성능이 느리다면 몇 가지 옵션이 있어요.
where연산자에 조건을 더 추가해 질의를 더 좁힌다.- 질의에
limit파라미터를 추가한다. - 범위 기반 필터링이 필요한 프로퍼티에
indexRangeFilters를 구성한다. 역인덱스 파라미터는 컬렉션을 만들 때 설정할 수 있어요.
특수 케이스
id로 필터링
객체 id를 기준으로도 필터를 걸 수 있어요.
속성 길이로 필터링 (len())
프로퍼티 길이를 기준으로 필터링할 수 있어요. 지원 범위는 이래요.
- 문자열·텍스트: 문자 수 (유니코드 문자인
世도 한 글자로 침) - 숫자, 불리언, geo 좌표, 전화번호, 데이터 블롭은 지원하지 않아요.
path 값은 프로퍼티 이름을 len()으로 감싼 문자열이에요. 예를 들어 title 프로퍼티 길이로 필터링하려면 path: ["len(title)"]을 써요. title 길이가 10보다 큰 Article을 찾으려면 이렇게 해요.
{
Get {
Article (
where: {
operator: GreaterThan,
valueInt: 10,
path: ["len(title)"]
}
)
}
}
지원 연산자는 (not) equal과 greater/less than (equal)이고, 값은 0 이상이어야 해요. 속성 길이로 필터링하려면 대상 클래스가 길이 인덱싱을 하도록 구성되어 있어야 해요.
크로스 레퍼런스로 필터링
크로스 레퍼런스(beacon)의 프로퍼티 값으로도 검색할 수 있어요. 예를 들어 inPublication이 "New Yorker"로 설정된 Article 객체를 선택하는 필터 같은 방식이에요.
중첩 객체 프로퍼티로 필터링 (Preview)
Weaviate v1.38부터 미리보기로 제공되는 기능이에요. 서버에서 WEAVIATE_PREVIEW_NESTED_FILTERING=on으로 게이트되고, object/object[] 프로퍼티 안쪽의 leaf를 대상으로 where 필터를 걸 수 있어요. path는 점으로 이어진 경로를 담은 단일 요소 배열이고, [N]은 세그먼트를 배열 인덱스에 고정해요. 예를 들어 "같은 차가 Toyota이면서 red인" 같은 같은 요소 상관(correlation)을 다룰 수 있어요.
geo 좌표로 필터링
geo 좌표는 Where 필터의 특수 케이스예요. 이 필터는 Get{} 함수에서만 지원돼요. geoCoordinates 프로퍼티 타입을 설정했다면 킬로미터 단위의 반경 안을 검색할 수 있어요. geo 좌표는 내부적으로 벡터 인덱스를 사용한다는 점이 특징이고, 현재 geo 좌표 필터링은 원점에서 가까운 800개 결과로 제한되며, 이후 다른 필터 조건과 검색 파라미터로 더 줄어들 수 있어요.
null 상태로 필터링
필터로 null 상태를 지정하려면 대상 클래스가 이를 인덱싱하도록 구성되어 있어야 해요.