Beispiele für einfache Suchabfragen in Azure KI-Suche
In Azure AI Search ruft die einfache Abfragesyntax den Standard-Abfrageparser für die Volltextsuche auf. Der Parser ist schnell und eignet sich für gängige Szenarien, einschließlich Volltextsuche, Filter- und Facettensuche und Präfixsuche. In diesem Artikel wird die Verwendung der einfachen Syntax in einer Anforderung zum Durchsuchen von Dokumenten (REST-API) anhand von Beispielen veranschaulicht.
Hinweis
Eine alternative Abfragesyntax ist die Lucene, die komplexere Abfragestrukturen wie z. B. die Fuzzysuche und die Platzhaltersuche unterstützt. Weitere Informationen finden Sie unter Beispiele für die vollständige Lucene-Suchsyntax.
Beispielindex für Hotels
Die folgenden Abfragen basieren auf dem „hotels-sample-index“, den Sie erstellen können, indem Sie die Anweisungen im Schnellstart: Erstellen eines Suchindex im Azure-Portal befolgen.
Beispielabfragen werden mithilfe der REST-API und POST-Anforderungen formuliert. Sie können sie in einen REST-Clienteinfügen und ausführen. Sie können auch die JSON-Ansicht des Such-Explorers im Azure-Portal verwenden. In der JSON-Ansicht können Sie die hier gezeigten Abfragebeispiele in diesem Artikel einfügen.
Anforderungsheader müssen die folgenden Werte aufweisen:
Schlüssel | Wert |
---|---|
Inhaltsart | Anwendung/json |
api-key | <your-search-service-api-key> , entweder Abfrage- oder Administratorschlüssel |
URI-Parameter müssen Ihren Suchdienstendpunkt mit dem Indexnamen, den Dokumentationssammlungen, dem Suchbefehl und der API-Version enthalten, ähnlich wie im folgenden Beispiel gezeigt:
https://{{service-name}}.search.windows.net/indexes/hotels-sample-index/docs/search?api-version=2024-07-01
Der Anforderungstext muss als gültiger JSON-Code vorliegen:
{
"search": "*",
"queryType": "simple",
"select": "HotelId, HotelName, Category, Tags, Description",
"count": true
}
Wenn
search
auf „*“ festgelegt ist, erfolgt die Abfrage ohne Angaben und entspricht einer NULL-Suche oder leeren Suche. Es ist nicht besonders nützlich, aber es ist die einfachste Suche, die Sie durchführen können, und sie zeigt alle abrufbaren Felder im Index mit allen Werten.queryType
ist standardmäßig auf simple festgelegt und kann ausgelassen werden. Hier ist dieser Ausdruck jedoch enthalten, um zu verdeutlichen, dass die Abfragebeispiele in diesem Artikel in einfacher Syntax ausgedrückt werden.select
ist auf eine durch Trennzeichen getrennte Liste von Feldern festgelegt und wird zur Zusammenstellung von Suchergebnissen verwendet. Es werden nur die Felder einbezogen, die im Kontext von Suchergebnissen nützlich sind.count
gibt die Anzahl der Dokumente zurück, die mit den Suchkriterien übereinstimmen. Bei einem leeren Suchbegriff werden alle Dokumente im Index gezählt (50 im „hotels-sample-index“).
Beispiel 1: Volltextsuche
Die Volltextsuche kann eine beliebige Anzahl von eigenständigen Begriffen oder in Anführungszeichen eingeschlossenen Ausdrücken mit oder ohne boolesche Operatoren sein.
POST /indexes/hotel-samples-index/docs/search?api-version=2024-07-01
{
"search": "pool spa +airport",
"searchMode": "any",
"queryType": "simple",
"select": "HotelId, HotelName, Category, Description",
"count": true
}
Eine Schlüsselwortsuche, die aus wichtigen Begriffen oder Ausdrücken besteht, funktioniert tendenziell am besten. Zeichenfolgenfelder werden bei der Indizierung und Abfrage einer Textanalyse unterzogen, wobei unwesentliche Wörter wie der, und oder es weggelassen werden. Wenn Sie sehen möchten, wie eine Abfragezeichenfolge im Index mit Token versehen wird, übergeben Sie die Zeichenfolge in einem Textanalyse-Aufruf an den Index.
Der searchMode
-Parameter steuert die Genauigkeit und den Abruf. Wenn Sie mehr Abrufe benötigen, verwenden Sie den Standardwert any. Dieser gibt ein Ergebnis zurück, wenn ein beliebiger Teil der Abfragezeichenfolge übereinstimmt. Wenn Sie ein genaues Ergebnis bevorzugen, bei dem alle Teile der Zeichenfolge übereinstimmen müssen, ändern Sie searchMode
in all. Testen Sie die obige Abfrage mit beiden Optionen, um zu sehen, wie „searchMode“ das Ergebnis beeinflusst.
Das Ergebnis der Abfrage pool spa +airport sollte in etwa wie im folgenden (gekürzten) Beispiel aussehen.
"@odata.count": 6,
"value": [
{
"@search.score": 7.3617697,
"HotelId": "21",
"HotelName": "Nova Hotel & Spa",
"Description": "1 Mile from the airport. Free WiFi, Outdoor Pool, Complimentary Airport Shuttle, 6 miles from the beach & 10 miles from downtown.",
"Category": "Resort and Spa",
"Tags": [
"pool",
"continental breakfast",
"free parking"
]
},
{
"@search.score": 2.5560288,
"HotelId": "25",
"HotelName": "Scottish Inn",
"Description": "Newly Redesigned Rooms & airport shuttle. Minutes from the airport, enjoy lakeside amenities, a resort-style pool & stylish new guestrooms with Internet TVs.",
"Category": "Luxury",
"Tags": [
"24-hour front desk service",
"continental breakfast",
"free wifi"
]
},
{
"@search.score": 2.2988036,
"HotelId": "35",
"HotelName": "Suites At Bellevue Square",
"Description": "Luxury at the mall. Located across the street from the Light Rail to downtown. Free shuttle to the mall and airport.",
"Category": "Resort and Spa",
"Tags": [
"continental breakfast",
"air conditioning",
"24-hour front desk service"
]
}
]
Beachten Sie die Suchbewertung („search.score“) im Ergebnis. Dies ist die Relevanzbewertung der Übereinstimmung. Standardmäßig liefert ein Suchdienst die 50 besten Treffer auf der Grundlage dieser Punktzahl.
Zu einer einheitlichen Bewertung von 1.0 kommt es, wenn kein Rang vorliegt, weil es entweder keine Volltextsuche war oder weil keine Kriterien angegeben wurden. Beispielsweise werden bei einer leeren Suche (search=*
) Zeilen in beliebiger Reihenfolge zurückgegeben. Wenn Sie tatsächliche Kriterien einfügen, werden aussagekräftige Werte für die Suchbewertungen angezeigt.
Beispiel 2: Suchen anhand der ID
Wenn Sie bei einer Abfrage Suchergebnisse erhalten, ist ein logischer nächster Schritt die Bereitstellung einer Detailseite, die weitere Felder des Dokuments enthält. In diesem Beispiel wird veranschaulicht, wie Sie ein einzelnes Dokument mithilfe von Dokument abrufen zurückgeben, indem Sie die Dokument-ID übergeben.
GET /indexes/hotels-sample-index/docs/41?api-version=2024-07-01
Alle Dokumente verfügen über einen eindeutigen Bezeichner. Wenn Sie das Portal verwenden, wählen Sie den Index auf der Registerkarte Indizes aus und sehen Sie sich dann die Felddefinitionen an, um festzustellen, welches Feld der Schlüssel ist. Bei Verwendung von REST gibt der Aufruf Get Index die Indexdefinition im Antworttext zurück.
Die Antwort für die obige Abfrage besteht aus dem Dokument mit dem Schlüssel 41. Alle Felder, die in der Indexdefinition als abrufbar gekennzeichnet sind, können in den Suchergebnissen zurückgegeben und in Ihrer App gerendert werden.
{
"HotelId": "41",
"HotelName": "Ocean Air Motel",
"Description": "Oceanfront hotel overlooking the beach features rooms with a private balcony and 2 indoor and outdoor pools. Various shops and art entertainment are on the boardwalk, just steps away.",
"Description_fr": "L'hôtel front de mer surplombant la plage dispose de chambres avec balcon privé et 2 piscines intérieures et extérieures. Divers commerces et animations artistiques sont sur la promenade, à quelques pas.",
"Category": "Budget",
"Tags": [
"pool",
"air conditioning",
"bar"
],
"ParkingIncluded": true,
"LastRenovationDate": "1951-05-10T00:00:00Z",
"Rating": 3.5,
"Location": {
"type": "Point",
"coordinates": [
-157.846817,
21.295841
],
"crs": {
"type": "name",
"properties": {
"name": "EPSG:4326"
}
}
},
"Address": {
"StreetAddress": "1450 Ala Moana Blvd 2238 Ala Moana Ctr",
"City": "Honolulu",
"StateProvince": "HI",
"PostalCode": "96814",
"Country": "USA"
}
}
Beispiel 3: Filtern nach Text
Die Filtersyntax ist ein OData-Ausdruck, den Sie allein oder mit search
verwenden können. Bei gemeinsamer Verwendung wird filter
zuerst auf den gesamten Index angewendet und dann wird die Suche auf die Ergebnisse des Filters angewendet. Filter können daher eine nützliche Methode zum Verbessern der Abfrageleistung darstellen, da sie die Menge der Dokumente reduzieren, die bei der Suchabfrage verarbeitet werden müssen.
Filter können für jedes Feld definiert werden, das in der Indexdefinition mit filterable
gekennzeichnet ist. Für „hotels-sample-index“ gehören Category, Tags, ParkingIncluded, Rating und die meisten Adressfelder zu den filterbaren Feldern.
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "art tours",
"queryType": "simple",
"filter": "Category eq 'Resort and Spa'",
"searchFields": "HotelName,Description,Category",
"select": "HotelId,HotelName,Description,Category",
"count": true
}
Die Antwort auf die obige Abfrage wird auf die Hotels beschränkt, die als Report and Spa kategorisiert sind und die Begriffe art oder tours enthalten. In diesem Fall gibt es nur eine Übereinstimmung.
{
"@search.score": 2.8576312,
"HotelId": "31",
"HotelName": "Santa Fe Stay",
"Description": "Nestled on six beautifully landscaped acres, located 2 blocks from the Plaza. Unwind at the spa and indulge in art tours on site.",
"Category": "Resort and Spa"
}
Beispiel 4: Filterfunktionen
Filterausdrücke können die Funktionen „search.ismatch“ und „search.ismatchscoring“ enthalten, sodass Sie eine Suchabfrage innerhalb des Filters erstellen können. Dieser Filterausdruck verwendet einen Platzhalter für free, um die enthaltenen Zusatzleistungen wie z. B. kostenloses WLAN oder kostenloses Parken auszuwählen.
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "",
"filter": "search.ismatch('free*', 'Tags', 'full', 'any')",
"select": "HotelId, HotelName, Category, Description",
"count": true
}
Die Antwort auf die obigen Abfrage enthält Übereinstimmungen mit 19 Hotels, die kostenlose Zusatzleistungen anbieten. Beachten Sie, dass die Suchbewertung in den gesamten Ergebnissen einheitlich 1.0 lautet. Dies liegt daran, dass der Suchausdruck NULL oder leer ist. So erhalten Sie wörtliche Filterübereinstimmungen, es wird jedoch keine Volltextsuche durchgeführt. Relevanzbewertungen werden nur bei einer Volltextsuche zurückgegeben. Wenn Sie Filter ohne search
verwenden, stellen Sie sicher, dass Sie genügend sortierbare Felder haben, damit Sie den Suchrang kontrollieren können.
"@odata.count": 19,
"value": [
{
"@search.score": 1.0,
"HotelId": "31",
"HotelName": "Santa Fe Stay",
"Tags": [
"view",
"restaurant",
"free parking"
]
},
{
"@search.score": 1.0,
"HotelId": "27",
"HotelName": "Super Deluxe Inn & Suites",
"Tags": [
"bar",
"free wifi"
]
},
{
"@search.score": 1.0,
"HotelId": "39",
"HotelName": "Whitefish Lodge & Suites",
"Tags": [
"continental breakfast",
"free parking",
"free wifi"
]
},
{
"@search.score": 1.0,
"HotelId": "11",
"HotelName": "Regal Orb Resort & Spa",
"Tags": [
"free wifi",
"restaurant",
"24-hour front desk service"
]
},
Beispiel 5: Bereichsfilter
Die Bereichsfilterung wird durch Filterausdrücke für jeden Datentyp unterstützt. In den folgenden Beispielen werden numerische Bereiche und Zeichenfolgenbereiche veranschaulicht. Datentypen sind bei Bereichsfiltern wichtig und funktionieren am besten bei numerischen Daten in numerischen Feldern und Zeichenfolgendaten in Zeichenfolgenfeldern. Numerische Daten in String-Feldern sind nicht für Bereiche geeignet, da numerische Strings nicht vergleichbar sind.
In der folgenden Abfrage wird ein numerischer Bereich verwendet. In „hotels-sample-index“ ist Rating
das einzige filterbare numerische Feld.
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "*",
"filter": "Rating ge 2 and Rating lt 4",
"select": "HotelId, HotelName, Rating",
"orderby": "Rating desc",
"count": true
}
Das Ergebnis dieser Abfrage sollte in etwa wie im folgenden (gekürzten) Beispiel aussehen.
"@odata.count": 27,
"value": [
{
"@search.score": 1.0,
"HotelId": "22",
"HotelName": "Stone Lion Inn",
"Rating": 3.9
},
{
"@search.score": 1.0,
"HotelId": "25",
"HotelName": "Scottish Inn",
"Rating": 3.8
},
{
"@search.score": 1.0,
"HotelId": "2",
"HotelName": "Twin Dome Motel",
"Rating": 3.6
}
...
Bei der nächsten Abfrage handelt es sich um einen Bereichsfilter für ein Zeichenfolgenfeld (Address/StateProvince):
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "*",
"filter": "Address/StateProvince ge 'A*' and Address/StateProvince lt 'D*'",
"select": "HotelId, HotelName, Address/StateProvince",
"count": true
}
Das Ergebnis dieser Abfrage sollte in etwa wie im folgenden (gekürzten) Beispiel aussehen. In diesem Beispiel ist es nicht möglich, nach StateProvince
zu sortieren, da das Feld in der Indexdefinition nicht als sortierbar eingestuft ist.
"@odata.count": 9,
"value": [
{
"@search.score": 1.0,
"HotelId": "9",
"HotelName": "Smile Hotel",
"Address": {
"StateProvince": "CA "
}
},
{
"@search.score": 1.0,
"HotelId": "39",
"HotelName": "Whitefish Lodge & Suites",
"Address": {
"StateProvince": "CO"
}
},
{
"@search.score": 1.0,
"HotelId": "7",
"HotelName": "Countryside Resort",
"Address": {
"StateProvince": "CA "
}
},
...
Beispiel 6: Geosuche
„hotels-sample-index“ enthält ein Feld Location mit Koordinaten für Breiten- und Längengrad. In diesem Beispiel wird die geo.distance-Funktion verwendet, mit der Dokumente im Umkreis eines Startpunkts bis zu einer beliebigen festgelegten Entfernung (in Kilometer) gefiltert werden. Sie können den letzten Wert in der Abfrage (10) anpassen, um die Fläche der Abfrage zu verkleinern oder zu vergrößern.
POST /indexes/v/docs/search?api-version=2024-07-01
{
"search": "*",
"filter": "geo.distance(Location, geography'POINT(-122.335114 47.612839)') le 10",
"select": "HotelId, HotelName, Address/City, Address/StateProvince",
"count": true
}
Im Ergebnis dieser Abfrage werden alle Hotels zurückgegeben, die innerhalb eines 10-Kilometer-Radius von den angegebenen Koordinaten liegen:
{
"@odata.count": 3,
"value": [
{
"@search.score": 1.0,
"HotelId": "45",
"HotelName": "Arcadia Resort & Restaurant",
"Address": {
"City": "Seattle",
"StateProvince": "WA"
}
},
{
"@search.score": 1.0,
"HotelId": "24",
"HotelName": "Gacc Capital",
"Address": {
"City": "Seattle",
"StateProvince": "WA"
}
},
{
"@search.score": 1.0,
"HotelId": "16",
"HotelName": "Double Sanctuary Resort",
"Address": {
"City": "Seattle",
"StateProvince": "WA"
}
}
]
}
Beispiel 7: Boolesche Werte mit searchMode
Die einfache Syntax unterstützt boolesche Operatoren in Form von Zeichen (+, -, |
) zur Unterstützung der Abfragelogik UND, ODER und NICHT. Die boolesche Suche verhält sich erwartungsgemäß, mit einigen bemerkenswerten Ausnahmen.
In den vorangegangenen Beispielen wurde der searchMode
-Parameter als Mechanismus zur Beeinflussung von Genauigkeit und Abruf eingeführt, wobei "searchMode": "any"
den Abruf begünstigt (ein Dokument, das eines der Kriterien erfüllt, gilt als Treffer) und "searchMode": "all"
die Genauigkeit (alle Kriterien müssen in einem Dokument übereinstimmen).
Im Zusammenhang mit einer booleschen Suche kann das Standard-"searchMode": "any"
verwirrend sein, wenn Sie eine Abfrage mit mehreren Operatoren kombinieren und breitere statt engere Ergebnisse erhalten. Dies gilt insbesondere für den Operator NICHT, bei dem die Ergebnisse alle Dokumente umfassen, die einen bestimmten Begriff nicht enthalten.
Dies wird im folgenden Beispiel veranschaulicht. Bei Ausführung der folgenden Abfrage mit searchMode „any“ werden 42 Dokumente zurückgegeben: diejenigen, die den Begriff restaurant enthalten, sowie alle Dokumente, die nicht den Ausdruck „*air conditioning“ aufweisen.
Beachten Sie, dass zwischen dem booleschen Operator (-
) und dem Ausdruck air conditioning kein Leerzeichen steht. Die Anführungszeichen sind mit Escapezeichen (\"
) versehen.
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "restaurant -\"air conditioning\"",
"searchMode": "any",
"searchFields": "Tags",
"select": "HotelId, HotelName, Tags",
"count": true
}
Der Wechsel zu "searchMode": "all"
erzwingt eine kumulative Wirkung auf die Kriterien und liefert ein kleineres Resultset (7 Treffer), das aus Dokumenten besteht, die den Begriff restaurant enthalten, abzüglich derjenigen, die den Ausdruck air conditioning enthalten.
Das Ergebnis dieser Abfrage sollte in etwa wie das folgende (gekürzte) Beispiel aussehen.
"@odata.count": 7,
"value": [
{
"@search.score": 2.5460577,
"HotelId": "11",
"HotelName": "Regal Orb Resort & Spa",
"Tags": [
"free wifi",
"restaurant",
"24-hour front desk service"
]
},
{
"@search.score": 2.166792,
"HotelId": "10",
"HotelName": "Countryside Hotel",
"Tags": [
"24-hour front desk service",
"coffee in lobby",
"restaurant"
]
},
...
Beispiel 8: Paginieren von Ergebnissen
In den vorangegangenen Beispielen haben Sie gelernt, welche Parameter sich auf die Zusammensetzung der Suchergebnisse auswirken, z. B. select
, das bestimmt, welche Felder in einem Ergebnis enthalten sind, die Sortierreihenfolge und wie man eine Zählung aller Treffer einfügt. Bei diesem Beispiel handelt es sich um eine Fortsetzung der Zusammenstellung von Suchergebnissen in Form von Paginierungsparametern, mit denen Sie die Anzahl der Ergebnisse, die auf einer beliebigen Seite angezeigt werden, in Batches zusammenfassen können.
Standardmäßig gibt ein Suchdienst die ersten 50 Übereinstimmungen zurück. Um die Anzahl der Treffer auf jeder Seite zu kontrollieren, verwenden Sie top
, um die Größe des Stapels festzulegen, und verwenden Sie dann skip
, um nachfolgende Stapel zu übernehmen.
Im folgenden Beispiel werden ein Filter und eine Sortierreihenfolge für das Feld Rating
verwendet („Rating“ ist sowohl filter- als auch sortierbar), da die Auswirkungen der Paginierung auf sortierte Ergebnisse einfacher zu erkennen sind. In einer regulären Volltextsuchabfrage werden die ersten Übereinstimmungen über @search.score
mit einem Rang versehen und paginiert.
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "*",
"filter": "Rating gt 4",
"select": "HotelName, Rating",
"orderby": "Rating desc",
"top": "5",
"count": true
}
Die Abfrage findet 21 übereinstimmende Dokumente. Da Sie jedoch top
angegeben haben, gibt die Antwort nur die ersten fünf Übereinstimmungen zurück, deren Bewertungen bei 4,9 beginnen und mit Lady of the Lake B & B bei 4,7 enden.
Überspringen Sie den ersten Batch, um die nächsten fünf Dokumente zu erhalten:
POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
"search": "*",
"filter": "Rating gt 4",
"select": "HotelName, Rating",
"orderby": "Rating desc",
"top": "5",
"skip": "5",
"count": true
}
In der Antwort für den zweiten Batch werden die ersten fünf Übereinstimmungen übersprungen und die nächsten fünf zurückgegeben, beginnend bei Pull‘r Inn Motel. Um mit weiteren Batches fortzufahren, behalten Sie für top
den Wert fünf bei und erhöhen dann bei jeder neuen Anforderung den Wert für skip
um fünf (skip=5, skip=10, skip=15 usw.).
"value": [
{
"@search.score": 1.0,
"HotelName": "Pull'r Inn Motel",
"Rating": 4.7
},
{
"@search.score": 1.0,
"HotelName": "Sublime Cliff Hotel",
"Rating": 4.6
},
{
"@search.score": 1.0,
"HotelName": "Antiquity Hotel",
"Rating": 4.5
},
{
"@search.score": 1.0,
"HotelName": "Nordick's Motel",
"Rating": 4.5
},
{
"@search.score": 1.0,
"HotelName": "Winter Panorama Resort",
"Rating": 4.5
}
]
Zugehöriger Inhalt
Nachdem Sie hier die grundlegende Abfragesyntax kennengelernt haben, versuchen Sie, Abfragen im Code anzugeben. Unter den folgenden Links wird erläutert, wie Suchabfragen mithilfe der Azure SDKs eingerichtet werden.
Eine zusätzliche Syntaxreferenz, eine Abfragearchitektur und Beispiele finden Sie unter den folgenden Links: