Składnia $filter OData w usłudze Azure AI Search

W usłudze Azure AI Search parametr $filter określa kryteria dołączania lub wykluczania dla zwracania dopasowań w wynikach wyszukiwania. W tym artykule opisano składnię OData $filter i przedstawiono przykłady.

Konstrukcja i stałe ścieżki pola są opisane w omówieniu języka OData w usłudze Azure AI Search. Aby uzyskać więcej informacji na temat scenariuszy filtrowania, zobacz Filtry w usłudze Azure AI Search.

Składnia

Filtr w języku OData jest wyrażeniem logicznym, które z kolei może być jednym z kilku typów wyrażeń, jak pokazano na poniższym formularzu EBNF (rozszerzony formularz Backus-Naur):

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

Dostępny jest również interakcyjny diagram składni:

Uwaga

Zobacz dokumentację składni wyrażeń OData dla usługi Azure AI Search , aby zapoznać się z pełną pełną NF.

Typy wyrażeń logicznych obejmują:

  • Wyrażenia filtru kolekcji używające polecenia any lub all. Stosują one kryteria filtrowania do pól kolekcji. Aby uzyskać więcej informacji, zobacz Operatory kolekcji OData w usłudze Azure AI Search.
  • Wyrażenia logiczne łączące inne wyrażenia logiczne przy użyciu operatorów and, ori not. Aby uzyskać więcej informacji, zobacz Operatory logiczne OData w usłudze Azure AI Search.
  • Wyrażenia porównania, które porównują pola lub zmienne zakresu z wartościami stałymi przy użyciu operatorów eq, , neltgt, , gei .le Aby uzyskać więcej informacji, zobacz Operatory porównania OData w usłudze Azure AI Search. Wyrażenia porównania są również używane do porównywania odległości między współrzędnymi geograficznymi przestrzennymi przy użyciu geo.distance funkcji . Aby uzyskać więcej informacji, zobacz Funkcje geoprzestrzewne OData w usłudze Azure AI Search.
  • Literały true logiczne i false. Te stałe mogą być przydatne czasami, gdy programowe generowanie filtrów, ale w przeciwnym razie nie są używane w praktyce.
  • Wywołania funkcji logicznych, w tym:
  • Ścieżki pól lub zmienne zakresu typu Edm.Boolean. Jeśli na przykład indeks zawiera pole logiczne o nazwie IsEnabled i chcesz zwrócić wszystkie dokumenty, w których to pole to true, wyrażenie filtru może być tylko nazwą IsEnabled.
  • Wyrażenia logiczne w nawiasach. Użycie nawiasów może pomóc jawnie określić kolejność operacji w filtrze. Aby uzyskać więcej informacji na temat domyślnego pierwszeństwa operatorów OData, zobacz następną sekcję.

Pierwszeństwo operatora w filtrach

Jeśli napiszesz wyrażenie filtru bez nawiasów wokół jego wyrażeń podrzędnych, usługa Azure AI Search oceni je zgodnie z zestawem reguł pierwszeństwa operatora. Te reguły są oparte na tym, które operatory są używane do łączenia wyrażeń podrzędnych. W poniższej tabeli wymieniono grupy operatorów w kolejności od najwyższego do najniższego pierwszeństwa:

Grupowy Operatory
Operatory logiczne not
Operatory porównania eq, , ne, gt, lt, , gele
Operatory logiczne and
Operatory logiczne or

Operator, który jest wyższy w powyższej tabeli, będzie "wiązać się bardziej ściśle" z operandami niż inne operatory. Na przykład and ma wyższy priorytet niż or, a operatory porównania mają wyższy priorytet niż jeden z nich, więc następujące dwa wyrażenia są równoważne:

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

Operator not ma najwyższy priorytet wszystkich — nawet wyższy niż operatory porównania. Dlatego w przypadku próby zapisania filtru w następujący sposób:

    not Rating gt 5

Zostanie wyświetlony następujący komunikat o błędzie:

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

Ten błąd występuje, ponieważ operator jest skojarzony tylko z Rating polem, które jest typu Edm.Int32, a nie z całym wyrażeniem porównania. Poprawką jest umieszczenie operandu not w nawiasach:

    not (Rating gt 5)

Ograniczenia rozmiaru filtru

Istnieją ograniczenia dotyczące rozmiaru i złożoności wyrażeń filtru, które można wysłać do usługi Azure AI Search. Limity są oparte mniej więcej na liczbie klauzul w wyrażeniu filtru. Dobrą wskazówką jest to, że jeśli masz setki klauzul, ryzykujesz przekroczenie limitu. Zalecamy zaprojektowanie aplikacji w taki sposób, aby nie generowała filtrów niezwiązanego rozmiaru.

Napiwek

search.in Użycie funkcji zamiast długich porównań równości może pomóc uniknąć limitu klauzuli filtru, ponieważ wywołanie funkcji jest liczone jako pojedyncza klauzula.

Przykłady

Znajdź wszystkie hotele z co najmniej jednym pokojem o podstawowej stawce mniejszej niż 200 USD, które są oceniane na poziomie lub powyżej 4:

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

Znajdź wszystkie hotele inne niż "Sea View Motel", które zostały odnowione od 2010 roku:

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

Znajdź wszystkie hotele, które zostały odnowione w 2010 roku lub później. Literał daty/godziny zawiera informacje o strefie czasowej pacyficznej (czas standardowy):

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

Znajdź wszystkie hotele, w których znajduje się parking i gdzie wszystkie pokoje są dla osób niepełnosprawnych:

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

- LUB -

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

Znajdź wszystkie hotele, które są luksusowe lub obejmują parking i mają ocenę 5:

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

Znajdź wszystkie hotele z tagiem "wifi" w co najmniej jednym pokoju (gdzie każdy pokój ma tagi przechowywane w Collection(Edm.String) polu):

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

Znajdź wszystkie hotele z dowolnymi pokojami:

    $filter=Rooms/any()

Znajdź wszystkie hotele, które nie mają pokoi:

    $filter=not Rooms/any()

Znajdź wszystkie hotele w ciągu 10 kilometrów od danego punktu odniesienia (gdzie Location jest polem typu Edm.GeographyPoint):

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

Znajdź wszystkie hotele w danym widoku opisanym jako wielokąt (gdzie Location jest polem typu Edm.GeographyPoint). Wielokąt musi być zamknięty, co oznacza, że pierwsze i ostatnie zestawy punktów muszą być takie same. Ponadto punkty muszą być wymienione w kolejności odwrotnej.

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

Znajdź wszystkie hotele, w których pole "Opis" ma wartość null. Pole będzie mieć wartość null, jeśli nigdy nie zostało ustawione, lub jeśli jawnie ustawiono wartość null:

    $filter=Description eq null

Znajdź wszystkie hotele o nazwie równej "Sea View motel" lub "Budget hotel". Te frazy zawierają spacje, a spacja jest domyślnym ogranicznikiem. Alternatywny ogranicznik można określić w cudzysłowie pojedynczym jako trzeci parametr ciągu:

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

Znajdź wszystkie hotele o nazwie równej 'Sea View motel' lub 'Budget hotel' oddzielone '|'):

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

Znajdź wszystkie hotele, w których wszystkie pokoje mają tag "wifi" lub "tub":

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

Znajdź dopasowanie na frazy w kolekcji, takie jak "gorące stojaki na ręczniki" lub "dołączane do włosów" w tagach.

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

Znajdź dokumenty ze słowem "nabrzeża". To zapytanie filtru jest identyczne z żądaniem wyszukiwania za pomocą search=waterfrontpolecenia .

    $filter=search.ismatchscoring('waterfront')

Znajdź dokumenty ze słowem "hostel" i ocena większa lub równa 4, lub dokumenty ze słowem "motel" i ocena równa 5. Nie można wyrazić tego żądania bez search.ismatchscoring funkcji, ponieważ łączy wyszukiwanie pełnotekstowe z operacjami filtrowania przy użyciu polecenia or.

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

Znajdź dokumenty bez słowa "luksus".

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

Znajdź dokumenty z frazą "widok oceanu" lub ocena równa 5. Zapytanie search.ismatchscoring zostanie wykonane tylko względem pól HotelName i Description. Dokumenty, które pasują tylko do drugiej klauzuli rozsyłania, zostaną zwrócone zbyt - hotele o Rating wartości równej 5. Te dokumenty zostaną zwrócone z wynikiem równym zero, aby wyjaśnić, że nie pasują one do żadnego z ocenianych części wyrażenia.

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

Znajdź hotele, w których terminy "hotel" i "lotnisko" nie różnią się od siebie więcej niż pięć wyrazów w opisie i gdzie wszystkie pokoje są bez palenia. To zapytanie używa pełnego języka zapytań Lucene.

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

Znajdź dokumenty, które mają wyraz rozpoczynający się literami "lux" w polu Opis. To zapytanie używa wyszukiwania prefiksów w połączeniu z search.ismatch.

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

Następne kroki