Azure AI 검색의 OData 컬렉션 필터 문제 해결

Azure AI 검색에서 컬렉션 필드를 필터링하려면 anyall 연산자람다 식과 함께 사용합니다. 람다 식은 컬렉션의 각 요소에 적용되는 하위 필터입니다.

필터 식의 모든 기능을 람다 식에서 사용할 수 있는 것은 아닙니다. 사용할 수 있는 기능은 필터링하려는 컬렉션 필드의 데이터 형식에 따라 다릅니다. 해당 컨텍스트에서 지원되지 않는 람다 식의 기능을 사용하려고 하면 오류가 발생할 수 있습니다. 컬렉션 필드에 복잡한 필터를 작성하는 동안 이러한 오류가 발생하는 경우 이 문서가 문제 해결에 도움이 될 것입니다.

일반 컬렉션 필터 오류

다음 표에서는 컬렉션 필터를 실행하려 할 때 발생할 수 있는 오류를 나열합니다. 해당 오류는 람다 식에서 지원되지 않는 필터 식 기능을 사용하는 경우에 발생합니다. 각 오류는 오류를 방지하기 위해 필터를 다시 작성하는 방법에 대한 지침을 제공합니다. 이 표에는 오류를 방지하는 방법에 대한 이 문서의 관련 섹션 링크도 포함되어 있습니다.

오류 메시지 상황 세부 정보
함수 ismatch 에는 범위 변수 's'에 바인딩된 매개 변수가 없습니다. 람다 식('any' 또는 'all') 내에서는 바인딩된 필드 참조만 지원됩니다. 그러나 함수가 람다 식 외부에 있도록 필터를 ismatch 변경하고 다시 시도할 수 있습니다. 람다 식 내에서 search.ismatch 또는 search.ismatchscoring 사용 복합 컬렉션 필터링 규칙
잘못된 람다 식입니다. Collection(Edm.String) 형식의 필드를 반복하는 람다 식에서 반대되는 같음 또는 같지 않음에 대한 테스트를 발견했습니다. 'any'의 경우 'x eq y' 또는 'search.in(...)' 형식의 식을 사용합니다. 'all'의 경우 'x ne y', 'not(x eq y)' 또는 'not search.in(...)' 형식의 식을 사용합니다. Collection(Edm.String) 형식 필드에 대한 필터링 문자열 컬렉션을 필터링 규칙
잘못된 람다 식입니다. 지원되지 않는 형식의 복합 부울 식을 찾았습니다. 'any'의 경우 DNF(Disjunctive Nomal Form)로 알려진 'ORs of ANDs' 식을 사용합니다. 예: (a and b) or (c and d) a, b, c 및 d는 비교 또는 같음 하위 식입니다. 'all'의 경우 CNF(Conjunctive Normal Form)로 알려진 'ANDs of ORs' 식을 사용합니다. 예를 들어 (a or b) and (c or d) a, b, c 및 d는 비교 또는 같지 않음 하위 식입니다. 비교 식의 예: 'x gt 5', 'x le 2'. 같음 식의 예: 'x eq 5'. 같지 않음 식의 예: 'x ne 5'. Collection(Edm.DateTimeOffset), Collection(Edm.Double), Collection(Edm.Int32) 또는 Collection(Edm.Int64) 형식 필드 필터링 비교 가능한 컬렉션 필터링 규칙
잘못된 람다 식입니다. Collection(Edm.GeographyPoint) 형식의 필드를 반복하는 람다 식에서 지원되지 않는 geo.distance() 또는 geo.intersects() 사용을 발견했습니다. 'any'의 경우 'lt'또는 'le' 연산자를 사용하여 geo.distance()를 비교하고 geo.intersects() 사용이 부정되지 않았는지 확인합니다. 'all'의 경우 'gt'또는 'ge' 연산자를 사용하여 geo.distance()를 비교하고 geo.intersects() 사용이 부정되었는지 확인합니다. Collection(Edm.GeographyPoint) 형식 필드에 대한 필터링 GeographyPoint 컬렉션 필터링 규칙
잘못된 람다 식입니다. Collection(Edm.GeographyPoint) 형식의 필드를 반복하는 람다 식에서는 복합 부울식이 지원되지 않습니다. 'any'의 경우 하위 식에 'or'를 조인합니다. 'and'는 지원되지 않습니다. 'all'의 경우 하위 식에 'and'를 조인합니다. 'or'는 지원되지 않습니다. Collection(Edm.String) 또는 Collection(Edm.GeographyPoint) 형식 필드 필터링 문자열 컬렉션을 필터링 규칙

GeographyPoint 컬렉션 필터링 규칙
잘못된 람다 식입니다. 비교 연산자 ('lt', 'le', 'gt', 또는 'ge' 중 하나)를 찾았습니다. Collection(Edm.String) 형식의 필드를 반복하는 람다 식에는 같음 연산자만 허용됩니다. 'any'의 경우 'x eq y' 형식의 식을 사용합니다. 'all'에는 'x ne y' 또는 'not(x eq y)' 형식의 식을 사용합니다. Collection(Edm.String) 형식 필드에 대한 필터링 문자열 컬렉션을 필터링 규칙

유효 컬렉션 필터 작성 방법

유효 컬렉션 필터 작성 규칙은 각 데이터 형식마다 다릅니다. 다음 섹션에서는 지원되는 필터 기능과 지원되지 않는 기능의 예를 표시하여 규칙을 설명합니다:

문자열 컬렉션 필터링 규칙

문자열 컬렉션에 대한 람다 식 내에서 사용할 수 있는 유일한 비교 연산자는 eqne입니다.

참고 항목

Azure AI 검색은 람다 식 내외부와 관계없이 문자열에 대해 lt/le/gt/ge 연산자를 지원하지 않습니다.

any 본문은 같음만 테스트할 수 있고 all 본문은 같지 않음만 테스트할 수 있습니다.

any 본문의 orall 본문의 and을 통해 여러 식을 결합할 수도 있습니다. search.in 함수는 같음 검사를 or와 결합하는 것과 동일하므로 any 본문에서도 허용됩니다. 반대로 all 본문에는 not search.in이 허용됩니다.

예를 들어 다음의 식이 허용됩니다:

  • tags/any(t: t eq 'books')
  • tags/any(t: search.in(t, 'books, games, toys'))
  • tags/all(t: t ne 'books')
  • tags/all(t: not (t eq 'books'))
  • tags/all(t: not search.in(t, 'books, games, toys'))
  • tags/any(t: t eq 'books' or t eq 'games')
  • tags/all(t: t ne 'books' and not (t eq 'games'))

이러한 식은 허용되지 않지만 다음을 수행합니다.

  • tags/any(t: t ne 'books')
  • tags/any(t: not search.in(t, 'books, games, toys'))
  • tags/all(t: t eq 'books')
  • tags/all(t: search.in(t, 'books, games, toys'))
  • tags/any(t: t eq 'books' and t ne 'games')
  • tags/all(t: t ne 'books' or not (t eq 'games'))

부울 컬렉션 필터링 규칙

Edm.Boolean 유형은 eqne 연산자만 지원합니다. 따라서 동일한 범위 변수를 and/or과 함께 검사하는 해당 절을 결합하는 것은 항상 Tautology나 Contradiction으로 이어질 수 있기 때문에 그다지 의미가 없습니다.

다음은 허용되는 부울 컬렉션에 대한 필터의 몇 가지 예입니다:

  • flags/any(f: f)
  • flags/all(f: f)
  • flags/any(f: f eq true)
  • flags/any(f: f ne true)
  • flags/all(f: not f)
  • flags/all(f: not (f eq true))

문자열 컬렉션과 달리 부울 컬렉션에는 람다 식에 사용할 수 있는 연산자에 대한 제한이 없습니다. eqne는 모두 any 또는 all의 본문에서 사용할 수 있습니다.

다음과 같은 식은 부울 컬렉션에 허용되지 않습니다:

  • flags/any(f: f or not f)
  • flags/any(f: f or f)
  • flags/all(f: f and not f)
  • flags/all(f: f and f eq true)

GeographyPoint 컬렉션 필터링 규칙

컬렉션의 형식 Edm.GeographyPoint 값은 서로 직접 비교할 수 없습니다. 대신 geo.distancegeo.intersects 함수에 대한 매개 변수로 사용해야합니다. geo.distance 함수는 차례로 비교 연산자 lt, le, gt 또는 ge 중 하나를 사용하여 거리 값과 비교해야 합니다. 이러한 규칙은 비콜렉션 Edm.GeographyPoint 필드에도 적용됩니다.

문자열 컬렉션과 마찬가지로 Edm.GeographyPoint 컬렉션에는 다양한 형식의 람다 식에서 지리 공간 함수를 사용하고 결합하는 방법에 대한 몇 가지 규칙이 있습니다:

  • geo.distance 함수와 함께 사용할 수 있는 비교 연산자는 람다 식의 형식에 따라 달라집니다. any의 경우 lt 또는 le만 사용할 수 있습니다. all의 경우 gt 또는 ge만 사용할 수 있습니다. 관련된 geo.distance식을 부정할 수 있지만 비교 연산자를 변경해야 합니다(geo.distance(...) lt xnot (geo.distance(...) ge x)geo.distance(...) le xnot (geo.distance(...) gt x)
  • all의 본문에서 geo.intersects 함수는 부정해야 합니다. 반대로 any의 본문에서 geo.intersects 함수는 부정해서는 안됩니다.
  • any의 본문에서 지리 공간 식은 or를 사용하여 결합할 수 있습니다. all의 본문에서 이러한 식은 and를 사용하여 결합할 수 있습니다.

위의 제한 사항은 문자열 컬렉션의 같음/같지 않음 제한 사항과 유사한 이유로 존재합니다. 해당 이유를 자세히 살펴보기 위해 Azure AI 검색의 OData 컬렉션 필터 이해를 참조하세요.

다음은 허용되는 Edm.GeographyPoint 컬렉션에 대한 필터의 몇 가지 예입니다:

  • locations/any(l: geo.distance(l, geography'POINT(-122 49)') lt 10)
  • locations/any(l: not (geo.distance(l, geography'POINT(-122 49)') ge 10) or geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
  • locations/all(l: geo.distance(l, geography'POINT(-122 49)') ge 10 and not geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))

다음과 같은 식은 Edm.GeographyPoint 컬렉션에 허용되지 않습니다.

  • locations/any(l: l eq geography'POINT(-122 49)')
  • locations/any(l: not geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
  • locations/all(l: geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
  • locations/any(l: geo.distance(l, geography'POINT(-122 49)') gt 10)
  • locations/all(l: geo.distance(l, geography'POINT(-122 49)') lt 10)
  • locations/any(l: geo.distance(l, geography'POINT(-122 49)') lt 10 and geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
  • locations/all(l: geo.distance(l, geography'POINT(-122 49)') le 10 or not geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))

비교 가능한 컬렉션 필터링 규칙

이 섹션은 다음 데이터 형식 모두에 적용됩니다:

  • Collection(Edm.DateTimeOffset)
  • Collection(Edm.Double)
  • Collection(Edm.Int32)
  • Collection(Edm.Int64)

Edm.Int32Edm.DateTimeOffset와 같은 형식은 eq, ne, lt, le, gtge의 여섯 가지 비교 연산자를 모두 지원합니다. 이러한 형식의 컬렉션에 대한 람다 식에는 해당 연산자를 사용하는 간단한 식을 포함할 수 있습니다. 이는 anyall 모두에 적용됩니다. 예를 들어 다음과 같은 필터가 허용됩니다:

  • ratings/any(r: r ne 5)
  • dates/any(d: d gt 2017-08-24T00:00:00Z)
  • not margins/all(m: m eq 3.5)

그러나 이러한 비교 식을 람다 식 내에서 더 복잡한 식으로 결합하는 방법에는 다음과 같은 제한 사항이 있습니다:

  • any에 대한 규칙:
    • 단순한 같지 않음 식은 다른 어떤 식과도 유용하게 결합할 수 없습니다. 예를 들어 다음과 같은 식이 허용됩니다:

      • ratings/any(r: r ne 5)

      그러나 다음과 같은 식은 허용되지 않습니다:

      • ratings/any(r: r ne 5 and r gt 2)

      이 식은 허용되지만 조건이 겹치므로 유용하지 않습니다:

      • ratings/any(r: r ne 5 or r gt 7)
    • eq, lt, le, gt 또는 ge와 관련된 간단한 비교 식을 and/or과 결합할 수 있습니다. 예시:

      • ratings/any(r: r gt 2 and r le 5)
      • ratings/any(r: r le 5 or r gt 7)
    • and(결합)과 결합된 비교 식은 or를 사용하여 추가로 결합할 수 있습니다. 이 양식은 부울 논리에서"DNF(Disjunctive Normal Form)"로 알려져 있습니다. 예시:

      • ratings/any(r: (r gt 2 and r le 5) or (r gt 7 and r lt 10))
  • all에 대한 규칙:
    • 단순한 같음 식은 다른 어떤 식과도 유용하게 결합할 수 없습니다. 예를 들어 다음과 같은 식이 허용됩니다:

      • ratings/all(r: r eq 5)

      그러나 다음과 같은 식은 허용되지 않습니다:

      • ratings/all(r: r eq 5 or r le 2)

      이 식은 허용되지만 조건이 겹치므로 유용하지 않습니다:

      • ratings/all(r: r eq 5 and r le 7)
    • ne, lt, le, gt 또는 ge와 관련된 간단한 비교 식을 and/or과 결합할 수 있습니다. 예시:

      • ratings/all(r: r gt 2 and r le 5)
      • ratings/all(r: r le 5 or r gt 7)
    • or(분리)과 결합된 비교 식은 and를 사용하여 추가로 결합할 수 있습니다. 이 양식은 부울 논리에서"CNF(Conjunctive Normal Form)"로 알려져 있습니다. 예시:

      • ratings/all(r: (r le 2 or gt 5) and (r lt 7 or r ge 10))

복합 컬렉션 필터링 규칙

복합 컬렉션에 대한 람다 식은 기본 형식 컬렉션에 대한 람다 식보다 훨씬 더 유연한 구문을 지원합니다. 두 가지 예외만 제외하고 외부에서 사용할 수 있는 이러한 람다 식에 모든 필터 구문을 사용할 수 있습니다.

먼저 search.ismatchsearch.ismatchscoring 함수는 람다 식 내에서 지원되지 않습니다. 자세한 내용은 Azure AI 검색의 OData 컬렉션 필터 이해를 참조하세요.

두 번째로, 범위 변수 (무료 변수)에 바인딩되지 않은 참조 필드는 허용되지 않습니다. 예를 들어 다음과 같은 두 개의 동일한 OData 필터 식을 고려합니다:

  1. stores/any(s: s/amenities/any(a: a eq 'parking')) and details/margin gt 0.5
  2. stores/any(s: s/amenities/any(a: a eq 'parking' and details/margin gt 0.5))

첫 번째 식은 허용되지만 두 번째 폼은 범위 변수s에 바인딩되지 않으므로 거부 details/margin 됩니다.

또한 이 규칙은 외부 범위에 바인딩된 변수가 있는 식으로 확장됩니다. 해당 변수는 표시되는 범위에 대하여 무료입니다. 예를 들어 첫 번째 식은 허용되지만 두 번째 해당 식은 s/name이 범위 변수 a의 범위에 대해 무료이기 때문에 허용되지 않습니다:

  1. stores/any(s: s/amenities/any(a: a eq 'parking') and s/name ne 'Flagship')
  2. stores/any(s: s/amenities/any(a: a eq 'parking' and s/name ne 'Flagship'))

람다 식에 바인딩된 변수만 포함되도록 필터를 구성하는 것이 항상 가능하기 때문에 이러한 제한 사항은 실제로는 문제가 되지 않습니다.

컬렉션 필터 규칙용 참고 자료

다음 표에서는 각 컬렉션 데이터 형식에 대해 유효한 필터를 구성하기 위한 규칙을 요약해서 보여줍니다.

데이터 형식 any가 있는 람다 식에서 허용되는 기능 all가 있는 람다 식에서 허용되는 기능
Collection(Edm.ComplexType) search.ismatchsearch.ismatchscoring을 제외한 모든 항목 동일
Collection(Edm.String) eq 또는 search.in와 비교

하위 식과 or 결합
ne 또는 not search.in()와 비교

하위 식과 and 결합
Collection(Edm.Boolean) eq 또는 ne와 비교 동일
Collection(Edm.GeographyPoint) lt 또는 le와 함께 geo.distance 사용

geo.intersects

하위 식과 or 결합
gt 또는 ge와 함께 geo.distance 사용

not geo.intersects(...)

하위 식과 and 결합
Collection(Edm.DateTimeOffset), Collection(Edm.Double), Collection(Edm.Int32)Collection(Edm.Int64) eq, ne, lt, gt, le 또는 ge를 사용하여 비교

or를 사용하여 다른 하위 식과 비교 결합

and을 사용하여 ne를 제외한 다른 하위 식과 비교 결합

DNF(Disjunctive Normal Form)에서 andor의 조합을 사용하는 식
eq, ne, lt, gt, le 또는 ge를 사용하여 비교

and를 사용하여 다른 하위 식과 비교 결합

or을 사용하여 eq를 제외한 다른 하위 식과 비교 결합

CNF(Conjunctive Normal Form)에서 andor의 조합을 사용하는 식

각 사례에 대해 유효한 필터를 구성하는 방법에 대한 예제는 유효한 컬렉션 필터를 작성하는 방법을 참조하세요.

필터를 자주 작성하고 첫 번째 원칙의 규칙을 이해하는 것이 단순히 기억하는 것 이상으로 도움이 되는 경우 Azure AI 검색의 OData 컬렉션 필터 이해를 참조하세요.

다음 단계