Esempi di query di ricerca semplici in Ricerca di intelligenza artificiale di Azure

In Azure AI Search, la sintassi di query semplice richiama il parser di query predefinito per la ricerca full-text. Il parser è veloce e gestisce scenari comuni, tra cui la ricerca full-text, la ricerca filtrata e in base a facet e la ricerca con prefisso. Questo articolo usa esempi per illustrare l'utilizzo della sintassi semplice in una richiesta di ricerca di documenti (API REST).

Nota

Una sintassi di query alternativa è Lucene, che supporta strutture di query più complesse, ad esempio la ricerca fuzzy e con caratteri jolly. Per altre informazioni, vedere Esempi di sintassi di ricerca Lucene completa.

Indice Hotels-sample

Le query seguenti si basano sull'indice hotels-sample-index, che è possibile creare seguendo le istruzioni riportate in Avvio rapido: Creare un indice di ricerca nella portale di Azure.

Le query di esempio sono articolate usando l'API REST e le richieste POST. È possibile incollarli ed eseguirli in un client REST. In alternativa, usare la visualizzazione JSON di Esplora ricerche nella portale di Azure. Nella visualizzazione JSON è possibile incollare gli esempi di query illustrati qui in questo articolo.

Le intestazioni della richiesta devono avere i valori seguenti:

Chiave valore
Content-Type application/json
api-key <your-search-service-api-key>, query o chiave di amministrazione

I parametri URI devono includere l'endpoint del servizio di ricerca con il nome dell'indice, le raccolte di documenti, il comando di ricerca e la versione dell'API, in modo analogo all'esempio seguente:

https://{{service-name}}.search.windows.net/indexes/hotels-sample-index/docs/search?api-version=2024-07-01

Il corpo della richiesta deve essere formato come JSON valido:

{
    "search": "*",
    "queryType": "simple",
    "select": "HotelId, HotelName, Category, Tags, Description",
    "count": true
}
  • search impostato su * è una query non specificata, equivalente a una ricerca null o vuota. Non è particolarmente utile, ma è la ricerca più semplice che è possibile eseguire e mostra tutti i campi recuperabili nell'indice, con tutti i valori.

  • queryType impostare su simple è il valore predefinito e può essere omesso, ma è incluso per sottolineare che gli esempi di query in questo articolo sono espressi nella sintassi semplice.

  • select impostato su un elenco delimitato da virgole di campi viene usato per la composizione dei risultati della ricerca, inclusi solo i campi utili nel contesto dei risultati della ricerca.

  • count restituisce il numero di documenti corrispondenti ai criteri di ricerca. In una stringa di ricerca vuota, il conteggio è tutti i documenti nell'indice (50 nell'indice hotels-sample-index).

La ricerca full-text può essere un numero qualsiasi di termini autonomi o frasi racchiuse tra virgolette, con o senza operatori booleani.

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
}

Una ricerca di parole chiave composta da termini o frasi importanti tende a funzionare meglio. I campi stringa vengono sottoposti a analisi del testo durante l'indicizzazione e l'esecuzione di query, eliminando parole non essenziali come e . Per vedere come una stringa di query viene tokenizzata nell'indice, passare la stringa in una chiamata Analyze Text all'indice.

Il searchMode parametro controlla la precisione e il richiamo. Se si desidera più richiamare, usare il valore predefinito qualsiasi , che restituisce un risultato se viene trovata una corrispondenza in qualsiasi parte della stringa di query. Se si preferisce la precisione, dove tutte le parti della stringa devono essere abbinate, passare searchMode a tutte. Provare la query precedente in entrambi i modi per vedere come searchMode modifica il risultato.

La risposta per la query pool spa +airport dovrebbe essere simile all'esempio seguente.

"@odata.count": 4,
"value": [
{
    "@search.score": 6.090657,
    "HotelId": "12",
    "HotelName": "Winter Panorama Resort",
    "Description": "Plenty of great skiing, outdoor ice skating, sleigh rides, tubing and snow biking. Yoga, group exercise classes and outdoor hockey are available year-round, plus numerous options for shopping as well as great spa services. Newly-renovated with large rooms, free 24-hr airport shuttle & a new restaurant. Rooms/suites offer mini-fridges & 49-inch HDTVs.",
    "Category": "Resort and Spa"
},
{
    "@search.score": 4.314683,
    "HotelId": "21",
    "HotelName": "Good Business Hotel",
    "Description": "1 Mile from the airport. Free WiFi, Outdoor Pool, Complimentary Airport Shuttle, 6 miles from Lake Lanier & 10 miles from downtown. Our business center includes printers, a copy machine, fax, and a work area.",
    "Category": "Suite"
},
{
    "@search.score": 3.575948,
    "HotelId": "27",
    "HotelName": "Starlight Suites",
    "Description": "Complimentary Airport Shuttle & WiFi. Book Now and save - Spacious All Suite Hotel, Indoor Outdoor Pool, Fitness Center, Florida Green certified, Complimentary Coffee, HDTV",
    "Category": "Suite"
},
{
    "@search.score": 2.6926985,
    "HotelId": "25",
    "HotelName": "Waterfront 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": "Suite"
}
]

Si noti il punteggio di ricerca nella risposta. Si tratta del punteggio di pertinenza della corrispondenza. Per impostazione predefinita, un servizio di ricerca restituisce le prime 50 corrispondenze in base a questo punteggio.

I punteggi uniformi di 1,0 si verificano quando non è presente alcuna classificazione, perché la ricerca non era full-text o perché non sono stati specificati criteri. Ad esempio, in una ricerca vuota (search=*), le righe tornano in ordine arbitrario. Se si includono criteri effettivi, i punteggi di ricerca si convertono in valori significativi.

Esempio 2: ricerca per ID

Dopo la restituzione dei risultati della ricerca, un passaggio successivo logico consiste nel fornire una pagina dei dettagli che include più campi del documento. In questo esempio viene illustrato come restituire un singolo documento usando Recupera documento passando l'ID documento.

GET /indexes/hotels-sample-index/docs/41?api-version=2024-07-01

Tutti i documenti dispongono di un identificatore unico. Se si usa il portale, selezionare l'indice nella scheda Indici e quindi esaminare le definizioni dei campi per determinare quale campo è la chiave. Nell'API REST la chiamata GET Index restituisce la definizione dell'indice nel corpo della risposta.

La risposta per la query precedente è costituita dal documento la cui chiave è 41. Qualsiasi campo contrassegnato come recuperabile nella definizione dell'indice può essere restituito nei risultati della ricerca e sottoposto a rendering nell'app.

{
    "HotelId": "41",
    "HotelName": "Windy Ocean Motel",
    "Description": "Oceanfront hotel overlooking the beach features rooms with a private balcony and 2 indoor and outdoor pools. Inspired by the natural beauty of the island, each room includes an original painting of local scenes by the owner. Rooms include a mini fridge, Keurig coffee maker, and flatscreen TV. Various shops and art entertainment are on the boardwalk, just steps away.",
    "Description_fr": "Cet hôtel en bord de mer donnant sur la plage propose des chambres dotées d'un balcon privé et de 2 piscines intérieure et extérieure. Inspiré par la beauté naturelle de l'île, chaque chambre comprend une peinture originale de scènes locales par le propriétaire. Les chambres comprennent un mini-réfrigérateur, une cafetière Keurig et une télévision à écran plat. Divers magasins et divertissements artistiques se trouvent sur la promenade, à quelques pas.",
    "Category": "Suite",
    "Tags": [
    "pool",
    "air conditioning",
    "bar"
    ],
    "ParkingIncluded": true,
    "LastRenovationDate": "2021-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"
    }
}

Esempio 3: filtrare in base al testo

La sintassi del filtro è un'espressione OData che si può usare con in modo autonomo o con search. Se usati insieme nella stessa richiesta, filter viene applicato prima all'intero indice e quindi search viene eseguito sui risultati del filtro. I filtri quindi possono essere un'utile tecnica per migliorare le prestazioni delle query perché riducono il set di documenti che la query di ricerca deve elaborare.

I filtri possono essere definiti in qualsiasi campo contrassegnato come filterable nella definizione dell'indice. Per hotels-sample-index, i campi filtrabili includono Category, Tags, ParkingIncluded, Rating e la maggior parte dei campi Address .

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
    "search": "art tours",
    "queryType": "simple",
    "filter": "Category eq 'Boutique'",
    "searchFields": "HotelName,Description,Category",
    "select": "HotelId,HotelName,Description,Category",
    "count": true
}

La risposta per la query precedente ha come ambito solo gli hotel classificati come Boutique e che includono i termini arte o tour. In questo caso, c'è solo una corrispondenza.

"value": [
{
    "@search.score": 1.2814453,
    "HotelId": "2",
    "HotelName": "Old Century Hotel",
    "Description": "The hotel is situated in a nineteenth century plaza, which has been expanded and renovated to the highest architectural standards to create a modern, functional and first-class hotel in which art and unique historical elements coexist with the most modern comforts. The hotel also regularly hosts events like wine tastings, beer dinners, and live music.",
    "Category": "Boutique"
}
]

Esempio 4: funzioni di filtro

Le espressioni di filtro possono includere le funzioni search.ismatch e search.ismatchscoring, consentendo di compilare una query di ricerca all'interno del filtro. Questa espressione di filtro usa un carattere jolly gratuito per selezionare servizi tra cui wi-fi gratuito, parcheggio gratuito e così via.

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
  {
    "search": "",
    "filter": "search.ismatch('free*', 'Tags', 'full', 'any')",
    "select": "HotelName, Tags, Description",
    "count": true
  }

La risposta per la query precedente corrisponde a 27 hotel che offrono servizi gratuiti. Si noti che il punteggio di ricerca è uniforme 1 nei risultati. Ciò è dovuto al fatto che l'espressione di ricerca è null o vuota, generando corrispondenze di filtro verbatim, ma nessuna ricerca full-text. I punteggi di pertinenza vengono restituiti solo nella ricerca full-text. Se si usano filtri senza search, assicurarsi di disporre di campi ordinabili sufficienti in modo da poter controllare la classificazione della ricerca.

  "@odata.count": 27,
  "value": [
    {
      "@search.score": 1,
      "HotelName": "Country Residence Hotel",
      "Description": "All of the suites feature full-sized kitchens stocked with cookware, separate living and sleeping areas and sofa beds. Some of the larger rooms have fireplaces and patios or balconies. Experience real country hospitality in the heart of bustling Nashville. The most vibrant music scene in the world is just outside your front door.",
      "Tags": [
        "laundry service",
        "restaurant",
        "free parking"
      ]
    },
    {
      "@search.score": 1,
      "HotelName": "Downtown Mix Hotel",
      "Description": "Mix and mingle in the heart of the city. Shop and dine, mix and mingle in the heart of downtown, where fab lake views unite with a cheeky design.",
      "Tags": [
        "air conditioning",
        "laundry service",
        "free wifi"
      ]
    },
    {
      "@search.score": 1,
      "HotelName": "Starlight Suites",
      "Description": "Complimentary Airport Shuttle & WiFi. Book Now and save - Spacious All Suite Hotel, Indoor Outdoor Pool, Fitness Center, Florida Green certified, Complimentary Coffee, HDTV",
      "Tags": [
        "pool",
        "coffee in lobby",
        "free wifi"
      ]
    },
. . .

Esempio 5: filtri di intervallo

Il filtro di intervallo è supportato tramite filtri di espressioni per qualsiasi tipo di dati. Negli esempi seguenti vengono illustrati gli intervalli numerici e di stringhe. I tipi di dati sono importanti nei filtri di intervallo e funzionano in modo ottimale quando i dati numerici si trovano nei campi numerici e i dati di tipo stringa nei campi stringa. I dati numerici nei campi stringa non sono adatti per gli intervalli perché le stringhe numeriche non sono confrontabili.

La query seguente è un intervallo numerico. In hotels-sample-index l'unico campo numerico filtrabile è Rating.

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
}

La risposta per questa query dovrebbe essere simile all'esempio seguente, tagliata per brevità.

"@odata.count": 27,
"value": [
{
    "@search.score": 1,
    "HotelId": "22",
    "HotelName": "Lion's Den Inn",
    "Rating": 3.9
},
{
    "@search.score": 1,
    "HotelId": "25",
    "HotelName": "Waterfront Scottish Inn",
    "Rating": 3.8
},
{
    "@search.score": 1,
    "HotelId": "2",
    "HotelName": "Old Century Hotel",
    "Rating": 3.6
},
...

La query successiva è un filtro di intervallo su un campo stringa (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
}

La risposta per questa query dovrebbe essere simile all'esempio seguente, tagliata per brevità. In questo esempio non è possibile eseguire l'ordinamento in StateProvince base al fatto che il campo non è attribuito come ordinabile nella definizione dell'indice.

{
  "@odata.count": 9,
  "value": [
    {
      "@search.score": 1,
      "HotelId": "39",
      "HotelName": "White Mountain Lodge & Suites",
      "Address": {
        "StateProvince": "CO"
      }
    },
    {
      "@search.score": 1,
      "HotelId": "9",
      "HotelName": "Smile Up Hotel",
      "Address": {
        "StateProvince": "CA "
      }
    },
    {
      "@search.score": 1,
      "HotelId": "7",
      "HotelName": "Roach Motel",
      "Address": {
        "StateProvince": "CA "
      }
    },
    {
      "@search.score": 1,
      "HotelId": "34",
      "HotelName": "Lakefront Captain Inn",
      "Address": {
        "StateProvince": "CT"
      }
    },
    {
      "@search.score": 1,
      "HotelId": "37",
      "HotelName": "Campus Commander Hotel",
      "Address": {
        "StateProvince": "CA "
      }
    },
. . . 

L'indice hotels-sample-include un campo Location con coordinate di latitudine e longitudine. Questo esempio usa la funzione geo.distance che applica il filtro ai documenti all'interno della circonferenza di un punto di partenza, fino a una distanza arbitraria (in chilometri) specificata. È possibile modificare l'ultimo valore nella query (10) per ridurre o aumentare l'area della query.

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
}

La risposta per questa query restituisce tutti gli hotel entro una distanza di 10 chilometri delle coordinate specificate:

{
  "@odata.count": 3,
  "value": [
    {
      "@search.score": 1,
      "HotelId": "45",
      "HotelName": "Happy Lake Resort & Restaurant",
      "Address": {
        "City": "Seattle",
        "StateProvince": "WA"
      }
    },
    {
      "@search.score": 1,
      "HotelId": "24",
      "HotelName": "Uptown Chic Hotel",
      "Address": {
        "City": "Seattle",
        "StateProvince": "WA"
      }
    },
    {
      "@search.score": 1,
      "HotelId": "16",
      "HotelName": "Double Sanctuary Resort",
      "Address": {
        "City": "Seattle",
        "StateProvince": "WA"
      }
    }
  ]
}

Esempio 7: valori booleani con searchMode

La sintassi semplice supporta gli operatori booleani sotto forma di caratteri (+, -, |) per supportare la logica di query AND, OR e NOT. La ricerca booleana si comporta come previsto, con alcune eccezioni degne di nota.

In una ricerca booleana prendere in considerazione l'aggiunta del searchMode parametro come meccanismo per influenzare la precisione e il richiamo. I valori validi includono "searchMode": "any" il richiamo a favore (un documento che soddisfa uno dei criteri viene considerato una corrispondenza) e "searchMode": "all" il favore della precisione (tutti i criteri devono essere corrispondenti in un documento).

Nel contesto di una ricerca booleana, l'impostazione predefinita "searchMode": "any" può generare confusione se si esegue lo stack di una query con più operatori e si ottengono risultati più ampi anziché più stretti. Ciò è particolarmente vero con NOT, dove i risultati includono tutti i documenti che non contengono un termine o una frase specifica.

Di seguito ne viene illustrato un esempio. La query cerca le corrispondenze nel ristorante che escludono la frase aria condizionata. Se si esegue la query seguente con searchMode (qualsiasi), vengono restituiti 43 documenti: quelli contenenti il termine ristorante, oltre a tutti i documenti che non hanno la frase *aria condizionata.

Si noti che non c'è spazio tra l'operatore booleano (-) e la frase aria condizionata. Le virgolette sono precedute da un carattere di escape (\").

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
}

La modifica di in "searchMode": "all" applica un effetto cumulativo sui criteri e restituisce un set di risultati più piccolo (sette corrispondenze) costituito da documenti contenenti il termine ristorante, meno quelli contenenti la frase aria condizionata.

La risposta per questa query sarà ora simile all'esempio seguente, tagliata per brevità.

{
  "@odata.count": 14,
  "value": [
    {
      "@search.score": 3.1383743,
      "HotelId": "18",
      "HotelName": "Ocean Water Resort & Spa",
      "Tags": [
        "view",
        "pool",
        "restaurant"
      ]
    },
    {
      "@search.score": 2.028083,
      "HotelId": "22",
      "HotelName": "Lion's Den Inn",
      "Tags": [
        "laundry service",
        "free wifi",
        "restaurant"
      ]
    },
    {
      "@search.score": 2.028083,
      "HotelId": "34",
      "HotelName": "Lakefront Captain Inn",
      "Tags": [
        "restaurant",
        "laundry service",
        "coffee in lobby"
      ]
    },
...

Esempio 8: paging dei risultati

Negli esempi precedenti sono stati illustrati i parametri che influiscono sulla composizione dei risultati della ricerca, inclusi selectche determinano quali campi si trovano in un risultato, ordinano gli ordini e come includere un conteggio di tutte le corrispondenze. Questo esempio è una continuazione della composizione dei risultati di ricerca sotto forma di parametri di paging che consentono di raggruppare in batch il numero di risultati visualizzati in una determinata pagina.

Per impostazione predefinita, un servizio di ricerca restituisce le prime 50 corrispondenze. Per controllare il numero di corrispondenze in ogni pagina, usare top, per definire le dimensioni del batch, e poi usare skip per raccogliere i batch successivi.

Nell'esempio seguente viene usato un filtro e un ordinamento per il Rating campo (Rating è filtrabile e ordinabile) perché è più facile visualizzare gli effetti del paging sui risultati ordinati. In una normale query di ricerca completa, le corrispondenze principali vengono classificate e viene fatto il paging in base a @search.score.

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
}

La query trova 21 documenti corrispondenti, ma poiché è stato specificato top, la risposta restituisce solo le prime cinque corrispondenze, con valutazioni a partire dalla versione 4.9 e che terminano alle 4.7 con Il Valore B & B.

Per ottenere i cinque successivi, ignorare il primo batch:

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
}

La risposta per il secondo batch ignora le prime cinque partite, restituendo i cinque successivi, a partire da Pull'r Inn Motel. Per continuare con più batch, mantenere top cinque e quindi incrementare skip di cinque per ogni nuova richiesta (skip=5, skip=10, skip=15 e così via).

{
  "@odata.count": 21,
  "value": [
    {
      "@search.score": 1,
      "HotelName": "Head Wind Resort",
      "Rating": 4.7
    },
    {
      "@search.score": 1,
      "HotelName": "Sublime Palace Hotel",
      "Rating": 4.6
    },
    {
      "@search.score": 1,
      "HotelName": "City Skyline Antiquity Hotel",
      "Rating": 4.5
    },
    {
      "@search.score": 1,
      "HotelName": "Nordick's Valley Motel",
      "Rating": 4.5
    },
    {
      "@search.score": 1,
      "HotelName": "Winter Panorama Resort",
      "Rating": 4.5
    }
  ]
}

Dopo aver fatto pratica con la sintassi di query di base, provare a specificare le query nel codice. Il collegamento seguente illustra come configurare le query di ricerca usando gli SDK di Azure.

Per maggiori riferimenti alla sintassi, all'architettura di query ed per altri esempi, vedere i collegamenti seguenti: