Azure Cognitive Search의 OData $filter 구문

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

필드 경로 생성 및 상수는 Azure Cognitive Search OData 언어 개요에 설명되어 있습니다. 필터 시나리오에 대한 자세한 내용은 Azure Cognitive 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 Cognitive Search의 OData 식 구문 참조를 참조하세요.

부울 식 형식에는 다음이 포함됩니다.

  • any 또는 all을 사용하는 컬렉션 필터 식. 이 식은 컬렉션 필드에 필터 조건을 적용합니다. 자세한 내용은 Azure Cognitive Search의 OData 컬렉션 연산자를 참조하세요.
  • and, or, not 연산자를 사용하여 다른 부울 식을 결합하는 논리 식. 자세한 내용은 Azure Cognitive Search의 OData 논리 연산자를 참조하세요.
  • eq, ne, gt, lt, ge, le 연산자를 사용하여 필드 또는 범위 변수를 상수 값과 비교하는 비교 식. 자세한 내용은 Azure Cognitive Search의 OData 비교 연산자를 참조하세요. 비교 식은 geo.distance 함수를 사용하여 지리 공간 좌표 사이의 거리를 비교하는 데에도 사용됩니다. 자세한 내용은 Azure Cognitive Search의 OData 지리 공간적 함수를 참조하세요.
  • 부울 리터럴 truefalse. 이 상수는 프로그래밍 방식으로 필터를 생성하는 경우에 가끔 유용할 수 있지만 그렇지 않은 경우에는 실제로 사용되지 않습니다.
  • 다음을 비롯한 부울 함수 호출
  • Edm.Boolean 형식의 필드 경로 또는 범위 변수. 예를 들어 인덱스에 IsEnabled라는 부울 필드가 있고 이 필드가 true인 모든 문서를 반환하려는 경우 필터 식으로 이름 IsEnabled만 사용해도 됩니다.
  • 괄호 안의 부울 식. 괄호를 사용하면 필터의 작업 순서를 명시적으로 결정하는 데 도움이 됩니다. OData 연산자의 기본 우선 순위에 대한 자세한 내용은 다음 섹션을 참조하세요.

필터의 연산자 우선 순위

하위 식 주위에 괄호를 사용하지 않고 필터 식을 작성하면 Azure Cognitive Search에서 연산자 우선 순위 규칙 집합에 따라 식을 계산합니다. 이 규칙은 하위 식을 결합하는 데 사용되는 연산자를 기반으로 합니다. 다음 표에는 연산자 그룹이 가장 높은 우선 순위부터 가장 낮은 우선 순위 순으로 나와 있습니다.

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

위의 표에서 우선 순위가 높은 연산자는 다른 연산자보다 해당 피연산자에 “더 긴밀하게 바인딩”됩니다. 예를 들어 andor보다 우선 순위가 높고 비교 연산자는 둘 중 하나보다 우선 순위가 높기 때문에 다음 두 식은 동일합니다.

    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 Cognitive Search로 보낼 수 있는 필터 식의 크기 및 복잡성은 제한됩니다. 이러한 제한은 대략적으로 필터 식의 절 수와 관련이 있습니다. 적절한 지침은 수백 개의 절이 있을 경우 한도에 도달할 위험이 있다는 것입니다. 제한 없는 크기의 필터를 생성하지 않도록 애플리케이션을 설계하는 것이 좋습니다.

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

등급이 4 이상이고 기본 요금이 $200 미만인 객실이 하나 이상 있는 호텔을 모두 찾습니다.

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

2010년 이후에 리모델링된 호텔 중에서 “Sea View Motel”을 제외한 호텔을 모두 찾습니다.

    $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()

지정된 참조 지점에서 10km 이내에 있는 호텔을 모두 찾습니다(LocationEdm.GeographyPoint 형식의 필드임).

    $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

이름이 ‘Sea View motel’이거나 ‘Budget hotel’인 호텔을 모두 찾습니다. 해당 구에는 공백이 포함되고 공백이 기본 구분 기호입니다. 대체 구분 기호를 작은따옴표로 묶어 세 번째 문자열 매개 변수로 지정할 수 있습니다.

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

이름이 '|'로 구분된 'Sea View motel'이거나 'Budget hotel'인 호텔을 모두 찾습니다.

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

모든 객실에 ‘wifi’ 또는 ‘tub’ 태그가 있는 호텔을 모두 찾습니다.

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

태그에서 ‘heated towel racks’ 또는 ‘hairdryer included’ 등의 컬렉션 내 구와 일치하는 항목을 찾습니다.

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

"waterfront" 단어를 포함하는 문서를 찾습니다. 이 필터 쿼리는 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')

구 "ocean view"를 포함하거나 등급이 5인 문서를 찾습니다. search.ismatchscoring 쿼리는 필드 HotelNameDescription에 대해서만 실행됩니다. 논리합의 두 번째 절에만 일치하는 문서(Rating이 5인 호텔)도 반환됩니다. 점수를 매긴 식의 어떤 부분과도 일치하지 않았음을 명확하게 나타내기 위해 해당 문서는 점수가 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')

다음 단계