Azure AI Search의 OData $filter 구문

Azure AI Search 에서 $filter 매개 변수는 검색 결과에서 일치 항목을 반환하기 위한 포함 또는 제외 조건을 지정합니다. 이 문서에서는 $filter의 OData 구문을 설명하고 예를 제공합니다.

필드 경로 생성 및 상수는 Azure AI Search의 OData 언어 개요에 설명되어 있습니다. 필터 시나리오에 대한 자세한 내용은 Azure AI Search의 필터를 참조하세요.

구문

OData 언어의 필터는 다음 EBNF(Extended Backus-Naur Form)에 표시된 것처럼 여러 식 유형 중 하나일 수 있는 부울 식입니다.

boolean_expression ::=
    collection_filter_expression
    | logical_expression
    | comparison_expression
    | boolean_literal
    | boolean_function_call
    | '(' boolean_expression ')'
    | variable

/* This can be a range variable in the case of a lambda, or a field path. */
variable ::= identifier | field_path

다음과 같은 대화형 구문 다이어그램도 사용할 수 있습니다.

참고 항목

전체 EBNF는 Azure AI Search에 대한 OData 식 구문 참조를 참조하세요.

부울 식의 형식은 다음과 같습니다.

  • any 또는 all을 사용하는 컬렉션 필터 식. 컬렉션 필드에 필터 조건을 적용합니다. 자세한 내용은 Azure AI Search의 OData 컬렉션 연산자를 참조하세요.
  • 연산andor자를 사용하여 다른 부울 식을 결합하는 논리 식 및 not. 자세한 내용은 Azure AI Search의 OData 논리 연산자를 참조하세요.
  • eq, ne, gt, lt, ge, le 연산자를 사용하여 필드 또는 범위 변수를 상수 값과 비교하는 비교 식. 자세한 내용은 Azure AI Search의 OData 비교 연산자를 참조하세요. 비교 식은 geo.distance 함수를 사용하여 지리 공간 좌표 사이의 거리를 비교하는 데에도 사용됩니다. 자세한 내용은 Azure AI Search의 OData 지역 공간 함수를 참조하세요.
  • 부울 리터럴 및 false.true 이러한 상수는 프로그래밍 방식으로 필터를 생성할 때 유용할 수 있지만 실제로는 사용하지 않는 경향이 있습니다.
  • 다음을 포함한 부울 함수에 대한 호출:
    • geo.intersects - 지정된 점이 지정된 다각형 내에 있는지 여부를 테스트합니다. 자세한 내용은 Azure AI Search의 OData 지역 공간 함수를 참조하세요.
    • search.in - 필드 또는 범위 변수와 값 목록의 각 값을 비교합니다. 자세한 내용은 Azure AI Search의 OData search.in 함수를 참조하세요.
    • search.ismatchsearch.ismatchscoring - 필터 컨텍스트에서 전체 텍스트 검색 작업을 실행합니다. 자세한 내용은 Azure AI Search의 OData 전체 텍스트 검색 함수를 참조하세요.
  • 형식 Edm.Boolean의 필드 경로 또는 범위 변수입니다. 예를 들어 인덱스의 부울 필드가 호출 IsEnabled 되고 이 필드가 있는 모든 문서를 반환하려는 경우 필터 식은 true이름 IsEnabled일 수 있습니다.
  • 괄호 안의 부울 식입니다. 괄호를 사용하면 필터에서 작업의 순서를 명시적으로 결정하는 데 도움이 될 수 있습니다. OData 연산자의 기본 우선 순위에 대한 자세한 내용은 다음 섹션을 참조하세요.

필터의 연산자 우선 순위

하위 식 주위에 괄호가 없는 필터 식을 작성하는 경우 Azure AI Search는 연산자 우선 순위 규칙 집합에 따라 평가합니다. 이러한 규칙은 하위 식을 결합하는 데 사용되는 연산자를 기반으로 합니다. 다음 표에는 가장 높은 우선 순위에서 가장 낮은 우선 순위의 순서로 연산자 그룹이 나열되어 있습니다.

그룹 연산자
논리 연산자 not
비교 연산자 eq, ne, gt, lt, gele
논리 연산자 and
논리 연산자 or

위의 표에서 더 높은 연산자는 다른 연산자보다 피연산자에 "더 단단히 바인딩"됩니다. 예를 들어 and 우선 순위 or가 더 높고 비교 연산자가 둘 중 하나보다 우선 순위가 높으므로 다음 두 식은 동일합니다.

    Rating gt 0 and Rating lt 3 or Rating gt 7 and Rating lt 10
    ((Rating gt 0) and (Rating lt 3)) or ((Rating gt 7) and (Rating lt 10))

not 연산자는 모두의 우선 순위가 가장 높으며 비교 연산자보다 훨씬 높습니다. 따라서 다음과 같은 필터를 작성하려고 합니다.

    not Rating gt 5

다음 오류 메시지가 표시됩니다.

    Invalid expression: A unary operator with an incompatible type was detected. Found operand type 'Edm.Int32' for operator kind 'Not'.

이 오류는 연산자가 전체 비교 식이 아니라 형식Edm.Int32인 필드와 연결 Rating 되기 때문에 발생합니다. 문제를 해결하려면 not의 피연산자를 괄호 안에 넣습니다.

    not (Rating gt 5)

필터 크기 제한 사항

Azure AI Search로 보낼 수 있는 필터 식의 크기와 복잡성에는 제한이 있습니다. 이러한 제한은 대략적으로 필터 식의 절 수와 관련이 있습니다. 좋은 지침은 수백 개의 절이 있는 경우 제한을 초과할 위험이 있다는 것입니다. 제한 없는 크기의 필터를 생성하지 않도록 애플리케이션을 설계하는 것이 좋습니다.

함수 호출이 단일 절로 계산되기 때문에 같음 비교의 긴 논리합 대신 search.in 함수를 사용하면 필터 절 한도를 피할 수 있습니다.

예제

기준 요금이 $200 미만인 객실이 4개 이상인 호텔을 모두 찾습니다.

    $filter=Rooms/any(room: room/BaseRate lt 200.0) and Rating ge 4

2010년부터 리모델링된 "씨뷰 모텔"을 제외한 모든 호텔을 찾아보세요.

    $filter=HotelName ne 'Sea View Motel' and LastRenovationDate ge 2010-01-01T00:00:00Z

2010년 이상에 리모델링된 모든 호텔을 찾아보세요. 날짜/시간 리터럴에는 태평양 표준시에 대한 표준 시간대 정보가 포함됩니다.

    $filter=LastRenovationDate ge 2010-01-01T00:00:00-08:00

주차장이 있고 모든 객실이 금연인 호텔을 모두 찾습니다.

    $filter=ParkingIncluded and Rooms/all(room: not room/SmokingAllowed)

- 또는 -

    $filter=ParkingIncluded eq true and Rooms/all(room: room/SmokingAllowed eq false)

럭셔리 호텔이거나 주차장이 포함되어 있고 등급이 5인 모든 호텔을 찾습니다.

    $filter=(Category eq 'Luxury' or ParkingIncluded eq true) and Rating eq 5

하나 이상의 방에서 태그가 "wifi"인 모든 호텔을 찾습니다(각 방에는 필드에 태그가 저장되어 Collection(Edm.String) 있음).

    $filter=Rooms/any(room: room/Tags/any(tag: tag eq 'wifi'))

모든 객실이 있는 호텔을 모두 찾습니다.

    $filter=Rooms/any()

객실이 없는 호텔을 모두 찾습니다.

    $filter=not Rooms/any()

지정된 참조 지점(형식 Edm.GeographyPoint필드)Location에서 10km 이내의 모든 호텔을 찾습니다.

    $filter=geo.distance(Location, geography'POINT(-122.131577 47.678581)') le 10

다각형( Location Edm.GeographyPoint 형식의 필드)으로 설명된 지정된 뷰포트 내의 모든 호텔을 찾습니다. 다각형은 닫혀 있어야 합니다. 즉, 첫 번째 점과 마지막 점 세트가 같아야 합니다. 또한 점이 시계 반대 방향으로 나열되어야 합니다.

    $filter=geo.intersects(Location, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))')

“Description” 필드가 Null인 호텔을 모두 찾습니다. 필드가 설정되지 않았거나 명시적으로 null로 설정된 경우 필드는 null이 됩니다.

    $filter=Description eq null

이름이 '씨 뷰 모텔' 또는 '버짓 호텔'과 같은 모든 호텔을 찾습니다.) 이러한 구에는 공백이 포함되고 공백은 기본 구분 기호입니다. 대체 구분 기호를 작은따옴표로 묶어 세 번째 문자열 매개 변수로 지정할 수 있습니다.

    $filter=search.in(HotelName, 'Sea View motel,Budget hotel', ',')

이름이 '|'으로 구분된 '씨뷰 모텔' 또는 '버짓 호텔'과 같은 이름의 모든 호텔을 찾습니다.

    $filter=search.in(HotelName, 'Sea View motel|Budget hotel', '|')

모든 객실에 'wifi' 또는 '욕조' 태그가 있는 모든 호텔을 찾습니다.

    $filter=Rooms/any(room: room/Tags/any(tag: search.in(tag, 'wifi, tub')))

태그에서 '가열된 수건 랙' 또는 '헤어드라이어 포함'과 같은 컬렉션 내의 구에서 일치하는 항목을 찾습니다.

    $filter=Rooms/any(room: room/Tags/any(tag: search.in(tag, 'heated towel racks,hairdryer included', ','))

"워터프론트"라는 단어가 있는 문서를 찾습니다. 이 필터 쿼리는 search=waterfront를 사용한 검색 요청과 동일합니다.

    $filter=search.ismatchscoring('waterfront')

"hostel"이라는 단어가 있고 등급이 4 이상인 문서 또는 "motel"이라는 단어가 있고 등급이 5인 문서를 찾습니다. 이 요청은 함수를 사용하여 or전체 텍스트 검색과 필터 작업을 결합하기 때문에 함수 없이 search.ismatchscoring 는 표현할 수 없습니다.

    $filter=search.ismatchscoring('hostel') and rating ge 4 or search.ismatchscoring('motel') and rating eq 5

"luxury"라는 단어가 없는 문서를 찾습니다.

    $filter=not search.ismatch('luxury')

"바다 보기" 또는 등급이 5인 문서를 찾습니다. 쿼리는 search.ismatchscoring 필드 HotelNameDescription에 대해서만 실행됩니다. 분리의 두 번째 절과 일치하는 문서도 반환됩니다( 5인 호텔 Rating ). 이러한 문서는 0과 같은 점수로 반환되어 식의 점수가 매칭된 부분과 일치하지 않음을 분명히 합니다.

    $filter=search.ismatchscoring('"ocean view"', 'Description,HotelName') or Rating eq 5

설명에서 "hotel"과 "airport"라는 용어가 5단어 이하인 호텔과 모든 객실이 금연을 하는 호텔을 찾아보세요. 이 쿼리는 전체 Lucene 쿼리 언어를 사용합니다.

    $filter=search.ismatch('"hotel airport"~5', 'Description', 'full', 'any') and not Rooms/any(room: room/SmokingAllowed)

설명 필드에서 문자 "lux"로 시작하는 단어가 있는 문서를 찾습니다. 이 쿼리는 접두사 검색을 .와 search.ismatch함께 사용합니다.

    $filter=search.ismatch('lux*', 'Description')

다음 단계