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
luball
. 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
,or
inot
. 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
, ,ne
lt
gt
, ,ge
i .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życiugeo.distance
funkcji . Aby uzyskać więcej informacji, zobacz Funkcje geoprzestrzewne OData w usłudze Azure AI Search. - Literały
true
logiczne ifalse
. 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:
geo.intersects
, który sprawdza, czy dany punkt znajduje się w danym wielokącie. Aby uzyskać więcej informacji, zobacz Funkcje geoprzestrzewne OData w usłudze Azure AI Search.search.in
, który porównuje pole lub zmienną zakresu z każdą wartością na liście wartości. Aby uzyskać więcej informacji, zobacz funkcja ODatasearch.in
w usłudze Azure AI Search.search.ismatch
isearch.ismatchscoring
, które wykonują operacje wyszukiwania pełnotekstowego w kontekście filtru. Aby uzyskać więcej informacji, zobacz Funkcje wyszukiwania pełnotekstowego OData w usłudze Azure AI Search.
- Ścieżki pól lub zmienne zakresu typu
Edm.Boolean
. Jeśli na przykład indeks zawiera pole logiczne o nazwieIsEnabled
i chcesz zwrócić wszystkie dokumenty, w których to pole totrue
, 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:
Grupuj | Operatory |
---|---|
Operatory logiczne | not |
Operatory porównania | eq , , ne , gt , lt , , ge le |
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=waterfront
polecenia .
$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')