Condividi tramite


Avvio rapido: Ricerca vettoriale

Nella guida rapida, utilizzi la libreria client Azure AI Search per Python per creare, caricare ed eseguire query su un indice vettoriale. La libreria client Python fornisce un'astrazione sulle API REST per le operazioni sugli indici.

In Ricerca di intelligenza artificiale di Azure, un indice vettoriale ha uno schema di indice che definisce i campi vettoriali e non vettoriali, una configurazione di ricerca vettoriale per gli algoritmi che creano lo spazio di embedding e le impostazioni delle definizioni dei campi vettoriali valutate in fase di query. Indici: crea o aggiorna (API REST) crea l'indice vettoriale.

Suggerimento

Prerequisiti

Configurare l'accesso

Prima di iniziare, assicurarsi di avere le autorizzazioni per accedere al contenuto e alle operazioni in Ricerca di intelligenza artificiale di Azure. Questa guida introduttiva utilizza Microsoft Entra ID per l'autenticazione e la gestione delle autorizzazioni basata sui ruoli. Per assegnare i ruoli, è necessario essere proprietario o amministratore accesso utenti . Se i ruoli non sono fattibili, usare invece l'autenticazione basata su chiave.

Per configurare l'accesso basato sui ruoli consigliato:

  1. Abilitare l'accesso in base al ruolo per il servizio di ricerca.

  2. Assegnare i ruoli seguenti all'account utente.

    • Collaboratore servizi di ricerca

    • Collaboratore ai dati dell'indice di ricerca

    • Lettore di dati dell'indice di ricerca

Ottenere l'endpoint

Ogni servizio ricerca di intelligenza artificiale di Azure ha un endpoint, ovvero un URL univoco che identifica e fornisce l'accesso alla rete al servizio. In una sezione successiva si specifica questo endpoint per connettersi al servizio di ricerca tramite programmazione.

Per ottenere l'endpoint:

  1. Accedere al portale di Azure e selezionare il servizio di ricerca.

  2. Nel riquadro sinistro selezionare Panoramica.

  3. Prendere nota dell'endpoint, che dovrebbe essere simile a https://my-service.search.windows.net.

Configurare l'ambiente

  1. Usare Git per clonare il repository di esempio.

    git clone https://github.com/Azure-Samples/azure-search-python-samples
    
  2. Passare alla cartella di avvio rapido e aprirla in Visual Studio Code.

    cd azure-search-python-samples/Quickstart-Vector-Search
    code .
    
  3. In sample.envsostituire il valore segnaposto per AZURE_SEARCH_ENDPOINT con l'URL ottenuto in Ottenere l'endpoint.

  4. Rinomina sample.env in .env.

    mv sample.env .env
    
  5. Aprire vector-search-quickstart.ipynb.

  6. Premere CTRL+MAIUSC+P, selezionare Notebook: Selezionare Kernel notebook e seguire le istruzioni per creare un ambiente virtuale. Selezionare requirements.txt per le dipendenze.

    Al termine, verrà visualizzata una .venv cartella nella directory del progetto.

  7. Per l'autenticazione senza chiave con Microsoft Entra ID, accedere all'account Azure. Se si hanno più sottoscrizioni, selezionare quella che contiene il servizio Ricerca intelligenza artificiale di Azure.

    az login
    

Eseguire il codice

  1. Eseguire la Install packages and set variables cella per installare i pacchetti necessari e caricare le variabili di ambiente.

  2. Eseguire le celle rimanenti in sequenza per creare un indice vettoriale, caricare documenti ed eseguire tipi diversi di query vettoriali.

Risultato

Ogni cella di codice stampa l'output sul notebook. L'esempio seguente è l'output di , che mostra i risultati della Single vector searchricerca vettoriale classificati in base al punteggio di somiglianza.

Total results: 7
- HotelId: 48, HotelName: Nordick's Valley Motel, Category: Boutique
- HotelId: 13, HotelName: Luxury Lion Resort, Category: Luxury
- HotelId: 4, HotelName: Sublime Palace Hotel, Category: Boutique
- HotelId: 49, HotelName: Swirling Currents Hotel, Category: Suite
- HotelId: 2, HotelName: Old Century Hotel, Category: Boutique

Informazioni sul codice

Annotazioni

I frammenti di codice in questa sezione potrebbero essere stati modificati per la leggibilità. Per un esempio funzionante completo, vedere il codice sorgente.

Dopo aver eseguito il codice, è possibile suddividere i passaggi principali:

  1. Creare un indice vettoriale
  2. Caricare documenti nell'indice
  3. Eseguire una query sull'indice

Creare un indice vettoriale

Prima di aggiungere contenuto a Ricerca di intelligenza artificiale di Azure, è necessario creare un indice per definire la modalità di archiviazione e strutturazione del contenuto.

Lo schema dell'indice è organizzato in base al contenuto dell'hotel. I dati di esempio sono costituiti da descrizioni vettoriali e non vettoriali di hotel fittizi. La creazione dello schema dell'indice avviene nella cella Create an index del notebook, incluso il campo vettoriale DescriptionVector.

fields = [
    SimpleField(name="HotelId", type=SearchFieldDataType.String, key=True, filterable=True),
    SearchableField(name="HotelName", type=SearchFieldDataType.String, sortable=True),
    SearchableField(name="Description", type=SearchFieldDataType.String),
    SearchField(
        name="DescriptionVector",
        type=SearchFieldDataType.Collection(SearchFieldDataType.Single),
        searchable=True,
        vector_search_dimensions=1536,
        vector_search_profile_name="my-vector-profile"
    ),
    SearchableField(name="Category", type=SearchFieldDataType.String, sortable=True, filterable=True, facetable=True),
    SearchField(name="Tags", type=SearchFieldDataType.Collection(SearchFieldDataType.String), searchable=True, filterable=True, facetable=True),
    # Additional fields omitted for brevity
]

Aspetti chiave:

  • Per definire un indice, creare un elenco di campi. Ogni campo viene creato usando un metodo helper che definisce il tipo di campo e le relative impostazioni.

  • Questo particolare indice supporta più funzionalità di ricerca:

  • La vector_search_dimensions proprietà deve corrispondere alle dimensioni di output del modello di incorporamento. Questo avvio rapido usa 1,536 dimensioni in corrispondenza al modello text-embedding-ada-002.

  • La configurazione di VectorSearch definisce l'algoritmo ANN (Approximate Nearest Neighbor). Gli algoritmi supportati includono HNSW (Hierarchical Navigable Small World) e KNN (K-Nearest Neighbor). Per altre informazioni, vedere Pertinenza nella ricerca vettoriale.

Caricare documenti nell'indice

Gli indici appena creati sono vuoti. Per popolare un indice e renderlo ricercabile, è necessario caricare documenti JSON conformi allo schema dell'indice.

In Ricerca di intelligenza artificiale di Azure i documenti fungono da input per l'indicizzazione e gli output per le query. Per semplicità, questa guida introduttiva fornisce documenti di hotel di esempio con vettori precompilate. Negli scenari di produzione, il contenuto viene spesso estratto da origini dati connesse e trasformato in JSON usando indicizzatori.

Le Create documents payload celle e Upload the documents caricano i documenti nell'indice.

documents = [
    # List of hotel documents with embedded 1536-dimension vectors
    # Each document contains: HotelId, HotelName, Description, DescriptionVector,
    # Category, Tags, ParkingIncluded, LastRenovationDate, Rating, Address, Location
]

search_client = SearchClient(
    endpoint=search_endpoint,
    index_name=index_name,
    credential=credential
)

result = search_client.upload_documents(documents=documents)
for r in result:
    print(f"Key: {r.key}, Succeeded: {r.succeeded}, ErrorMessage: {r.error_message}")

Il codice interagisce con un indice di ricerca specifico ospitato nel servizio Ricerca intelligenza artificiale di Azure tramite SearchClient, che è l'oggetto principale fornito dal azure-search-documents pacchetto. SearchClient fornisce l'accesso alle operazioni sugli indici, ad esempio:

  • Inserimento dati: upload_documents(), merge_documents(), delete_documents()

  • Operazioni di ricerca: search(), autocomplete(), suggest()

Eseguire una query sull'indice

Le query nel notebook illustrano modelli di ricerca diversi. Le query vettoriali di esempio si basano su due stringhe:

  • Stringa di ricerca full-text: "historic hotel walk to restaurants and shopping"

  • Stringa di query vettoriale: "quintessential lodging near running trails, eateries, retail" (vettorializzata in una rappresentazione matematica)

La stringa di query vettoriale è semanticamente simile alla stringa di ricerca full-text, ma include termini che non esistono nell'indice. Una ricerca di sola parola chiave per la stringa di query vettoriale restituisce zero risultati. Tuttavia, la ricerca vettoriale trova corrispondenze pertinenti in base al significato anziché alle parole chiave esatte.

Gli esempi seguenti iniziano con una query vettoriale di base e aggiungono progressivamente filtri, ricerca di parole chiave e reranking semantico.

La Single vector search cella illustra uno scenario di base in cui si desidera trovare descrizioni dei documenti che corrispondono strettamente alla stringa di query vettoriale. VectorizedQuery configura la ricerca vettoriale:

  • k_nearest_neighbors limita il numero di risultati restituiti in base alla somiglianza del vettore.
  • fields specifica il campo vettoriale su cui eseguire la ricerca.
vector_query = VectorizedQuery(
    vector=vector,
    k_nearest_neighbors=5,
    fields="DescriptionVector",
    kind="vector",
    exhaustive=True
)

results = search_client.search(
    vector_queries=[vector_query],
    select=["HotelId", "HotelName", "Description", "Category", "Tags"],
    top=5,
    include_total_count=True
)

Ricerca a vettore singolo con un filtro

In Ricerca di intelligenza artificiale di Azure i filtri si applicano ai campi non vettoriali in un indice. La Single vector search with filter cella filtra sul Tags campo per filtrare tutti gli hotel che non forniscono wi-fi gratuito.

# vector_query omitted for brevity

results = search_client.search(
    vector_queries=[vector_query],
    filter="Tags/any(tag: tag eq 'free wifi')",
    select=["HotelId", "HotelName", "Description", "Category", "Tags"],
    top=7,
    include_total_count=True
)

Ricerca a vettore singolo con un filtro geografico

È possibile specificare un filtro spaziale geografico per limitare i risultati a un'area geografica specifica. La Single vector search with geo filter cella specifica un punto geografico (Washington D.C., utilizzando coordinate di longitudine e latitudine) e restituisce gli hotel entro 300 chilometri. Il vector_filter_mode parametro determina quando viene eseguito il filtro. In questo caso, postFilter esegue il filtro dopo la ricerca vettoriale.

# vector_query omitted for brevity

results = search_client.search(
    include_total_count=True,
    top=5,
    select=[
        "HotelId", "HotelName", "Category", "Description", "Address/City", "Address/StateProvince"
    ],
    facets=["Address/StateProvince"],
    filter="geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",
    vector_filter_mode="postFilter",
    vector_queries=[vector_query]
)

La ricerca ibrida combina query full-text e vettoriali in una singola richiesta. La Hybrid search cella esegue simultaneamente entrambi i tipi di query e quindi usa La fusione di rango reciproco (RRF) per unire i risultati in una classificazione unificata. RRF usa l'inverso delle classifiche dei risultati di ogni set di risultati per produrre una classifica unificata. Si noti che i punteggi di ricerca ibrida sono uniformemente inferiori ai punteggi di query singola.

# vector_query omitted for brevity

results = search_client.search(
    search_text="historic hotel walk to restaurants and shopping",
    vector_queries=[vector_query],
    select=["HotelId", "HotelName", "Description", "Category", "Tags"],
    top=5,
    include_total_count=True
)

La Semantic hybrid search cella illustra la classificazione semantica, che classifica i risultati in base alla comprensione del linguaggio.

# vector_query omitted for brevity

results = search_client.search(
    search_text="historic hotel walk to restaurants and shopping",
    vector_queries=[vector_query],
    select=["HotelId", "HotelName", "Category", "Description"],
    query_type="semantic",
    semantic_configuration_name="my-semantic-config",
    top=5,
    include_total_count=True
)

Confrontare questi risultati con i risultati della ricerca ibrida della query precedente. Senza reranking semantico, Sublime Palace Hotel si classifica primo perché la fusione di rango reciproco (RRF) combina il testo e i punteggi vettoriali per produrre un risultato combinato. Dopo il reranking semantico, Swirling Currents Hotel si sposta al primo posto.

Il ranker semantico usa modelli di comprensione automatica per valutare il livello di corrispondenza di ogni risultato con la finalità della query. La descrizione dell'Hotel Swirling Currents menziona "walking access to shopping, dining, entertainment and the city center", che è strettamente allineata con la ricerca "walk to restaurants and shopping". Questa corrispondenza di rilevanza semantica per ristoranti e negozi nelle vicinanze lo colloca al di sopra del Sublime Palace Hotel, che nella descrizione non mette in evidenza servizi raggiungibili a piedi.

Aspetti chiave:

  • In una ricerca ibrida è possibile integrare la ricerca vettoriale con la ricerca full-text sulle parole chiave. I filtri e la classificazione semantica si applicano solo al contenuto testuale, non ai vettori.

  • I risultati effettivi includono più dettagli, tra cui didascalie semantiche ed evidenziazioni. Questo avvio rapido modifica i risultati per la leggibilità. Per ottenere la struttura completa della risposta, usare REST per eseguire la richiesta.

Pulire le risorse

Quando si lavora nella propria sottoscrizione, è consigliabile completare un progetto rimuovendo le risorse non più necessarie. Le risorse lasciate in esecuzione possono avere un costo.

Nel portale di Azure selezionare Tutte le risorse o Gruppidi risorse nel riquadro sinistro per trovare e gestire le risorse. È possibile eliminare le risorse singolarmente o eliminare il gruppo di risorse per rimuovere tutte le risorse contemporaneamente.

Altrimenti, è possibile eseguire la cella di codice Clean up per eliminare l'indice creato in questo avvio rapido.

In questa guida introduttiva, userai la libreria client Azure AI Search per Java per creare, caricare ed eseguire query su un indice vettoriale. La libreria client Java fornisce un'astrazione sulle API REST per le operazioni sugli indici.

In Ricerca di intelligenza artificiale di Azure, un indice vettoriale ha uno schema di indice che definisce i campi vettoriali e non vettoriali, una configurazione di ricerca vettoriale per gli algoritmi che creano lo spazio di embedding e le impostazioni delle definizioni dei campi vettoriali valutate in fase di query. Indici: crea o aggiorna (API REST) crea l'indice vettoriale.

Suggerimento

Prerequisiti

Configurare l'accesso

Prima di iniziare, assicurarsi di avere le autorizzazioni per accedere al contenuto e alle operazioni in Ricerca di intelligenza artificiale di Azure. Questa guida introduttiva utilizza Microsoft Entra ID per l'autenticazione e la gestione delle autorizzazioni basata sui ruoli. Per assegnare i ruoli, è necessario essere proprietario o amministratore accesso utenti . Se i ruoli non sono fattibili, usare invece l'autenticazione basata su chiave.

Per configurare l'accesso basato sui ruoli consigliato:

  1. Abilitare l'accesso in base al ruolo per il servizio di ricerca.

  2. Assegnare i ruoli seguenti all'account utente.

    • Collaboratore servizi di ricerca

    • Collaboratore ai dati dell'indice di ricerca

    • Lettore di dati dell'indice di ricerca

Ottenere l'endpoint

Ogni servizio ricerca di intelligenza artificiale di Azure ha un endpoint, ovvero un URL univoco che identifica e fornisce l'accesso alla rete al servizio. In una sezione successiva si specifica questo endpoint per connettersi al servizio di ricerca tramite programmazione.

Per ottenere l'endpoint:

  1. Accedere al portale di Azure e selezionare il servizio di ricerca.

  2. Nel riquadro sinistro selezionare Panoramica.

  3. Prendere nota dell'endpoint, che dovrebbe essere simile a https://my-service.search.windows.net.

Configurare l'ambiente

  1. Usare Git per clonare il repository di esempio.

    git clone https://github.com/Azure-Samples/azure-search-java-samples
    
  2. Passare alla cartella di avvio rapido e aprirla in Visual Studio Code.

    cd azure-search-java-samples/quickstart-vector-search
    code .
    
  3. In src/main/resources/application.propertiessostituire il valore segnaposto per azure.search.endpoint con l'URL ottenuto in Ottenere l'endpoint.

  4. Installa le dipendenze.

    mvn clean dependency:copy-dependencies
    

    Al termine della compilazione, verrà visualizzata una target/dependency cartella nella directory del progetto.

  5. Per l'autenticazione senza chiave con Microsoft Entra ID, accedere all'account Azure. Se si hanno più sottoscrizioni, selezionare quella che contiene il servizio Ricerca intelligenza artificiale di Azure.

    az login
    

Eseguire il codice

  1. Creare un indice vettoriale.

    mvn compile exec:java "-Dexec.mainClass=com.example.search.CreateIndex"
    
  2. Caricare documenti contenenti incorporamenti precompilate.

    mvn compile exec:java "-Dexec.mainClass=com.example.search.UploadDocuments"
    
  3. Eseguire una query di ricerca vettoriale.

    mvn compile exec:java "-Dexec.mainClass=com.example.search.SearchSingle"
    
  4. (Facoltativo) Eseguire varianti di query aggiuntive.

    mvn compile exec:java "-Dexec.mainClass=com.example.search.SearchSingleWithFilter"
    mvn compile exec:java "-Dexec.mainClass=com.example.search.SearchSingleWithFilterGeo"
    mvn compile exec:java "-Dexec.mainClass=com.example.search.SearchHybrid"
    mvn compile exec:java "-Dexec.mainClass=com.example.search.SearchSemanticHybrid"
    

Risultato

L'output di CreateIndex.java mostra il nome e la conferma dell'indice.

Using Azure Search endpoint: https://<search-service-name>.search.windows.net
Using Azure Search index: hotels-vector-quickstart
Creating index...
hotels-vector-quickstart created

L'output di UploadDocuments.java mostra lo stato di successo per ogni documento indicizzato.

Uploading documents...
Key: 1, Succeeded: true, ErrorMessage: none
Key: 2, Succeeded: true, ErrorMessage: none
Key: 3, Succeeded: true, ErrorMessage: none
Key: 4, Succeeded: true, ErrorMessage: none
Key: 48, Succeeded: true, ErrorMessage: none
Key: 49, Succeeded: true, ErrorMessage: none
Key: 13, Succeeded: true, ErrorMessage: none
Waiting for indexing... Current count: 0
All documents indexed successfully.

L'output di mostra i risultati della SearchSingle.java ricerca vettoriale classificati in base al punteggio di somiglianza.

Single Vector search found 5
- HotelId: 48, HotelName: Nordick's Valley Motel, Tags: ["continental breakfast","air conditioning","free wifi"], Score 0.6605852
- HotelId: 13, HotelName: Luxury Lion Resort, Tags: ["bar","concierge","restaurant"], Score 0.6333684
- HotelId: 4, HotelName: Sublime Palace Hotel, Tags: ["concierge","view","air conditioning"], Score 0.605672
- HotelId: 49, HotelName: Swirling Currents Hotel, Tags: ["air conditioning","laundry service","24-hour front desk service"], Score 0.6026341
- HotelId: 2, HotelName: Old Century Hotel, Tags: ["pool","free wifi","air conditioning","concierge"], Score 0.57902366

Informazioni sul codice

Annotazioni

I frammenti di codice in questa sezione potrebbero essere stati modificati per la leggibilità. Per un esempio funzionante completo, vedere il codice sorgente.

Dopo aver eseguito il codice, è possibile suddividere i passaggi principali:

  1. Creare un indice vettoriale
  2. Caricare documenti nell'indice
  3. Eseguire una query sull'indice

Creare un indice vettoriale

Prima di aggiungere contenuto a Ricerca di intelligenza artificiale di Azure, è necessario creare un indice per definire la modalità di archiviazione e strutturazione del contenuto.

Lo schema dell'indice è organizzato in base al contenuto dell'hotel. I dati di esempio sono costituiti da descrizioni vettoriali e non vettoriali di hotel fittizi. Il codice seguente in CreateIndex.java crea lo schema dell'indice, incluso il campo DescriptionVectorvettoriale .

// Define fields
List<SearchField> fields = Arrays.asList(
    new SearchField("HotelId", SearchFieldDataType.STRING)
        .setKey(true)
        .setFilterable(true),
    new SearchField("HotelName", SearchFieldDataType.STRING)
        .setSortable(true)
        .setSearchable(true),
    new SearchField("Description", SearchFieldDataType.STRING)
        .setSearchable(true),
    new SearchField("DescriptionVector",
        SearchFieldDataType.collection(SearchFieldDataType.SINGLE))
        .setSearchable(true)
        .setVectorSearchDimensions(1536)
        .setVectorSearchProfileName("my-vector-profile"),
    new SearchField("Category", SearchFieldDataType.STRING)
        .setSortable(true)
        .setFilterable(true)
        .setFacetable(true)
        .setSearchable(true),
    new SearchField("Tags", SearchFieldDataType.collection(
        SearchFieldDataType.STRING))
        .setSearchable(true)
        .setFilterable(true)
        .setFacetable(true),
    // Additional fields: ParkingIncluded, LastRenovationDate, Rating, Address, Location
);

var searchIndex = new SearchIndex(indexName, fields);

// Define vector search configuration
var hnswParams = new HnswParameters()
    .setM(16)
    .setEfConstruction(200)
    .setEfSearch(128);
var hnsw = new HnswAlgorithmConfiguration("hnsw-vector-config");
hnsw.setParameters(hnswParams);

var vectorProfile = new VectorSearchProfile(
    "my-vector-profile",
    "hnsw-vector-config");
var vectorSearch = new VectorSearch()
    .setAlgorithms(Arrays.asList(hnsw))
    .setProfiles(Arrays.asList(vectorProfile));
searchIndex.setVectorSearch(vectorSearch);

// Define semantic configuration
var prioritizedFields = new SemanticPrioritizedFields()
    .setTitleField(new SemanticField("HotelName"))
    .setContentFields(Arrays.asList(new SemanticField("Description")))
    .setKeywordsFields(Arrays.asList(new SemanticField("Category")));
var semanticConfig = new SemanticConfiguration(
    "semantic-config",
    prioritizedFields);
var semanticSearch = new SemanticSearch()
    .setConfigurations(Arrays.asList(semanticConfig));
searchIndex.setSemanticSearch(semanticSearch);

// Define suggesters
var suggester = new SearchSuggester("sg", Arrays.asList("HotelName"));
searchIndex.setSuggesters(Arrays.asList(suggester));

// Create the search index
SearchIndex result = searchIndexClient.createOrUpdateIndex(searchIndex);

Aspetti chiave:

  • Per definire un indice, creare un elenco di campi.

  • Questo particolare indice supporta più funzionalità di ricerca:

  • Il setVectorSearchDimensions() valore deve corrispondere alle dimensioni di output del modello di incorporamento. Questo avvio rapido usa 1,536 dimensioni in corrispondenza al modello text-embedding-ada-002.

  • La configurazione di VectorSearch definisce l'algoritmo ANN (Approximate Nearest Neighbor). Gli algoritmi supportati includono HNSW (Hierarchical Navigable Small World) e KNN (K-Nearest Neighbor). Per altre informazioni, vedere Pertinenza nella ricerca vettoriale.

Caricare documenti nell'indice

Gli indici appena creati sono vuoti. Per popolare un indice e renderlo ricercabile, è necessario caricare documenti JSON conformi allo schema dell'indice.

In Ricerca di intelligenza artificiale di Azure i documenti fungono da input per l'indicizzazione e gli output per le query. Per semplicità, questa guida introduttiva fornisce documenti di hotel di esempio con vettori precompilate. Negli scenari di produzione, il contenuto viene spesso estratto da origini dati connesse e trasformato in JSON usando indicizzatori.

Il codice seguente in UploadDocuments.java carica i documenti nel servizio di ricerca.

// Documents contain hotel data with 1536-dimension vectors for DescriptionVector
static final List<Map<String, Object>> DOCUMENTS = Arrays.asList(
    new HashMap<>() {{
        put("@search.action", "mergeOrUpload");
        put("HotelId", "1");
        put("HotelName", "Stay-Kay City Hotel");
        put("Description", "This classic hotel is fully-refurbished...");
        put("DescriptionVector", Arrays.asList(/* 1536 float values */));
        put("Category", "Boutique");
        put("Tags", Arrays.asList("view", "air conditioning", "concierge"));
        // Additional fields...
    }}
    // Additional hotel documents
);

// Upload documents to the index
IndexDocumentsResult result = searchClient.uploadDocuments(DOCUMENTS);
for (IndexingResult r : result.getResults()) {
    System.out.println("Key: %s, Succeeded: %s".formatted(r.getKey(), r.isSucceeded()));
}

Il codice interagisce con un indice di ricerca specifico ospitato nel servizio Ricerca intelligenza artificiale di Azure tramite SearchClient, che è l'oggetto principale fornito dal azure-search-documents pacchetto. SearchClient fornisce l'accesso a operazioni quali:

  • Inserimento dati: uploadDocuments, mergeDocuments, deleteDocuments

  • Operazioni di ricerca: search, autocomplete, suggest

Eseguire una query sull'indice

Le query nei file di ricerca illustrano modelli di ricerca diversi. Le query vettoriali di esempio si basano su due stringhe:

  • Stringa di ricerca full-text: "historic hotel walk to restaurants and shopping"

  • Stringa di query vettoriale: "quintessential lodging near running trails, eateries, retail" (vettorializzata in una rappresentazione matematica)

La stringa di query vettoriale è semanticamente simile alla stringa di ricerca full-text, ma include termini che non esistono nell'indice. Una ricerca di sola parola chiave per la stringa di query vettoriale restituisce zero risultati. Tuttavia, la ricerca vettoriale trova corrispondenze pertinenti in base al significato anziché alle parole chiave esatte.

Gli esempi seguenti iniziano con una query vettoriale di base e aggiungono progressivamente filtri, ricerca di parole chiave e reranking semantico.

SearchSingle.java illustra uno scenario di base in cui si desidera trovare descrizioni di documenti che corrispondano strettamente alla stringa di query vettoriale. VectorizedQuery configura la ricerca vettoriale:

  • setKNearestNeighborsCount() limita il numero di risultati restituiti in base alla somiglianza del vettore.
  • setFields() specifica il campo vettoriale su cui eseguire la ricerca.
var vectorQuery = new VectorizedQuery(QueryVector.getVectorList())
    .setKNearestNeighborsCount(5)
    .setFields("DescriptionVector")
    .setExhaustive(true);

var vectorSearchOptions = new VectorSearchOptions()
    .setQueries(vectorQuery)
    .setFilterMode(VectorFilterMode.POST_FILTER);

var searchOptions = new SearchOptions()
    .setTop(7)
    .setIncludeTotalCount(true)
    .setSelect("HotelId", "HotelName", "Description", "Category", "Tags")
    .setVectorSearchOptions(vectorSearchOptions);

var results = searchClient.search("*", searchOptions, Context.NONE);

for (SearchResult result : results) {
    SearchDocument document = result.getDocument(SearchDocument.class);
    System.out.println("HotelId: %s, HotelName: %s, Score: %s".formatted(
        document.get("HotelId"), document.get("HotelName"), result.getScore()));
}

Ricerca a vettore singolo con un filtro

In Ricerca di intelligenza artificiale di Azure i filtri si applicano ai campi non vettoriali in un indice. SearchSingleWithFilter.java filtri sul Tags campo per filtrare tutti gli hotel che non forniscono wi-fi gratuito.

var vectorQuery = new VectorizedQuery(QueryVector.getVectorList())
    .setKNearestNeighborsCount(5)
    .setFields("DescriptionVector")
    .setExhaustive(true);

var vectorSearchOptions = new VectorSearchOptions()
    .setQueries(vectorQuery)
    .setFilterMode(VectorFilterMode.POST_FILTER);

// Add filter for "free wifi" tag
var searchOptions = new SearchOptions()
    .setTop(7)
    .setIncludeTotalCount(true)
    .setSelect("HotelId", "HotelName", "Description", "Category", "Tags")
    .setFilter("Tags/any(tag: tag eq 'free wifi')")
    .setVectorSearchOptions(vectorSearchOptions);

var results = searchClient.search("*", searchOptions, Context.NONE);

Ricerca a vettore singolo con un filtro geografico

È possibile specificare un filtro spaziale geografico per limitare i risultati a un'area geografica specifica. SearchSingleWithGeoFilter.java specifica un punto geografico (Washington D.C., utilizzando coordinate di longitudine e latitudine) e restituisce gli hotel entro 300 chilometri. Il setFilterMode metodo , chiamato su VectorSearchOptions, determina quando viene eseguito il filtro. In questo caso, POST_FILTER esegue il filtro dopo la ricerca vettoriale.

var searchOptions = new SearchOptions()
    .setTop(5)
    .setIncludeTotalCount(true)
    .setSelect("HotelId", "HotelName", "Category", "Description",
               "Address/City", "Address/StateProvince")
    .setFacets("Address/StateProvince")
    .setFilter("geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300")
    .setVectorSearchOptions(vectorSearchOptions);

La ricerca ibrida combina query full-text e vettoriali in una singola richiesta. SearchHybrid.java esegue entrambi i tipi di query contemporaneamente e quindi usa La fusione tra rango reciproco (RRF) per unire i risultati in una classificazione unificata. RRF usa l'inverso delle classifiche dei risultati di ogni set di risultati per produrre una classifica unificata. Si noti che i punteggi di ricerca ibrida sono uniformemente inferiori ai punteggi di query singola.

var vectorQuery = new VectorizedQuery(QueryVector.getVectorList())
    .setKNearestNeighborsCount(5)
    .setFields("DescriptionVector")
    .setExhaustive(true);

var vectorSearchOptions = new VectorSearchOptions()
    .setQueries(vectorQuery)
    .setFilterMode(VectorFilterMode.POST_FILTER);

var searchOptions = new SearchOptions()
    .setTop(5)
    .setIncludeTotalCount(true)
    .setSelect("HotelId", "HotelName", "Description", "Category", "Tags")
    .setVectorSearchOptions(vectorSearchOptions);

// Pass both text query and vector search options
var results = searchClient.search(
    "historic hotel walk to restaurants and shopping",
    searchOptions, Context.NONE);

SearchSemanticHybrid.java illustra la classificazione semantica, che classifica i risultati in base alla comprensione del linguaggio.

var vectorQuery = new VectorizedQuery(QueryVector.getVectorList())
    .setKNearestNeighborsCount(5)
    .setFields("DescriptionVector")
    .setExhaustive(true);

var vectorSearchOptions = new VectorSearchOptions()
    .setQueries(vectorQuery)
    .setFilterMode(VectorFilterMode.POST_FILTER);

SemanticSearchOptions semanticSearchOptions = new SemanticSearchOptions()
    .setSemanticConfigurationName("semantic-config");

var searchOptions = new SearchOptions()
    .setTop(5)
    .setIncludeTotalCount(true)
    .setSelect("HotelId", "HotelName", "Category", "Description")
    .setQueryType(QueryType.SEMANTIC)
    .setSemanticSearchOptions(semanticSearchOptions)
    .setVectorSearchOptions(vectorSearchOptions);

var results = searchClient.search(
    "historic hotel walk to restaurants and shopping",
    searchOptions, Context.NONE);

Confrontare questi risultati con i risultati della ricerca ibrida della query precedente. Senza reranking semantico, Sublime Palace Hotel si classifica primo perché la fusione di rango reciproco (RRF) combina il testo e i punteggi vettoriali per produrre un risultato combinato. Dopo il reranking semantico, Swirling Currents Hotel si sposta al primo posto.

Il ranker semantico usa modelli di comprensione automatica per valutare il livello di corrispondenza di ogni risultato con la finalità della query. La descrizione dell'Hotel Swirling Currents menziona "walking access to shopping, dining, entertainment and the city center", che è strettamente allineata con la ricerca "walk to restaurants and shopping". Questa corrispondenza di rilevanza semantica per ristoranti e negozi nelle vicinanze lo colloca al di sopra del Sublime Palace Hotel, che nella descrizione non mette in evidenza servizi raggiungibili a piedi.

Aspetti chiave:

  • In una ricerca ibrida è possibile integrare la ricerca vettoriale con la ricerca full-text sulle parole chiave. I filtri e la classificazione semantica si applicano solo al contenuto testuale, non ai vettori.

  • I risultati effettivi includono più dettagli, tra cui didascalie semantiche ed evidenziazioni. Questo avvio rapido modifica i risultati per la leggibilità. Per ottenere la struttura completa della risposta, usare REST per eseguire la richiesta.

Pulire le risorse

Quando si lavora nella propria sottoscrizione, è consigliabile completare un progetto rimuovendo le risorse non più necessarie. Le risorse lasciate in esecuzione possono avere un costo.

Nel portale di Azure selezionare Tutte le risorse o Gruppidi risorse nel riquadro sinistro per trovare e gestire le risorse. È possibile eliminare le risorse singolarmente o eliminare il gruppo di risorse per rimuovere tutte le risorse contemporaneamente.

In caso contrario, eseguire il comando seguente per eliminare l'indice creato in questa guida introduttiva.

mvn compile exec:java "-Dexec.mainClass=com.example.search.DeleteIndex"

In questa guida introduttiva, si usa la libreria client di Ricerca Intelligenza Artificiale di Azure per JavaScript per creare, caricare ed eseguire query su un indice vettoriale. La libreria client JavaScript fornisce un'astrazione sulle API REST per le operazioni sugli indici.

In Ricerca di intelligenza artificiale di Azure, un indice vettoriale ha uno schema di indice che definisce i campi vettoriali e non vettoriali, una configurazione di ricerca vettoriale per gli algoritmi che creano lo spazio di embedding e le impostazioni delle definizioni dei campi vettoriali valutate in fase di query. Indici: crea o aggiorna (API REST) crea l'indice vettoriale.

Suggerimento

Prerequisiti

Configurare l'accesso

Prima di iniziare, assicurarsi di avere le autorizzazioni per accedere al contenuto e alle operazioni in Ricerca di intelligenza artificiale di Azure. Questa guida introduttiva utilizza Microsoft Entra ID per l'autenticazione e la gestione delle autorizzazioni basata sui ruoli. Per assegnare i ruoli, è necessario essere proprietario o amministratore accesso utenti . Se i ruoli non sono fattibili, usare invece l'autenticazione basata su chiave.

Per configurare l'accesso basato sui ruoli consigliato:

  1. Abilitare l'accesso in base al ruolo per il servizio di ricerca.

  2. Assegnare i ruoli seguenti all'account utente.

    • Collaboratore servizi di ricerca

    • Collaboratore ai dati dell'indice di ricerca

    • Lettore di dati dell'indice di ricerca

Ottenere l'endpoint

Ogni servizio ricerca di intelligenza artificiale di Azure ha un endpoint, ovvero un URL univoco che identifica e fornisce l'accesso alla rete al servizio. In una sezione successiva si specifica questo endpoint per connettersi al servizio di ricerca tramite programmazione.

Per ottenere l'endpoint:

  1. Accedere al portale di Azure e selezionare il servizio di ricerca.

  2. Nel riquadro sinistro selezionare Panoramica.

  3. Prendere nota dell'endpoint, che dovrebbe essere simile a https://my-service.search.windows.net.

Configurare l'ambiente

  1. Usare Git per clonare il repository di esempio.

    git clone https://github.com/Azure-Samples/azure-search-javascript-samples
    
  2. Passare alla cartella di avvio rapido e aprirla in Visual Studio Code.

    cd azure-search-javascript-samples/quickstart-vector-js
    code .
    
  3. In sample.envsostituire il valore segnaposto per AZURE_SEARCH_ENDPOINT con l'URL ottenuto in Ottenere l'endpoint.

  4. Rinomina sample.env in .env.

    mv sample.env .env
    
  5. Installa le dipendenze.

    npm install
    

    Al termine dell'installazione, verrà visualizzata una node_modules cartella nella directory del progetto.

  6. Per l'autenticazione senza chiave con Microsoft Entra ID, accedere all'account Azure. Se si hanno più sottoscrizioni, selezionare quella che contiene il servizio Ricerca intelligenza artificiale di Azure.

    az login
    

Eseguire il codice

  1. Creare un indice vettoriale.

    node -r dotenv/config src/createIndex.js
    
  2. Caricare documenti contenenti incorporamenti precompilate.

    node -r dotenv/config src/uploadDocuments.js
    
  3. Eseguire una query di ricerca vettoriale.

    node -r dotenv/config src/searchSingle.js
    
  4. (Facoltativo) Eseguire varianti di query aggiuntive.

    node -r dotenv/config src/searchSingleWithFilter.js
    node -r dotenv/config src/searchSingleWithFilterGeo.js
    node -r dotenv/config src/searchHybrid.js
    node -r dotenv/config src/searchSemanticHybrid.js
    

Risultato

L'output di createIndex.js mostra il nome e la conferma dell'indice.

Using Azure Search endpoint: https://<search-service-name>.search.windows.net
Using Azure Search index: hotels-vector-quickstart
Creating index...
hotels-vector-quickstart created

L'output di uploadDocuments.js mostra lo stato di successo per ogni documento indicizzato.

Uploading documents...
Key: 1, Succeeded: true, ErrorMessage: none
Key: 2, Succeeded: true, ErrorMessage: none
Key: 3, Succeeded: true, ErrorMessage: none
Key: 4, Succeeded: true, ErrorMessage: none
Key: 48, Succeeded: true, ErrorMessage: none
Key: 49, Succeeded: true, ErrorMessage: none
Key: 13, Succeeded: true, ErrorMessage: none
Waiting for indexing... Current count: 0
All documents indexed successfully.

L'output di mostra i risultati della searchSingle.js ricerca vettoriale classificati in base al punteggio di somiglianza.

Single Vector search found 5
- HotelId: 48, HotelName: Nordick's Valley Motel, Tags: ["continental breakfast","air conditioning","free wifi"], Score 0.6605852
- HotelId: 13, HotelName: Luxury Lion Resort, Tags: ["bar","concierge","restaurant"], Score 0.6333684
- HotelId: 4, HotelName: Sublime Palace Hotel, Tags: ["concierge","view","air conditioning"], Score 0.605672
- HotelId: 49, HotelName: Swirling Currents Hotel, Tags: ["air conditioning","laundry service","24-hour front desk service"], Score 0.6026341
- HotelId: 2, HotelName: Old Century Hotel, Tags: ["pool","free wifi","air conditioning","concierge"], Score 0.57902366

Informazioni sul codice

Annotazioni

I frammenti di codice in questa sezione potrebbero essere stati modificati per la leggibilità. Per un esempio funzionante completo, vedere il codice sorgente.

Dopo aver eseguito il codice, è possibile suddividere i passaggi principali:

  1. Creare un indice vettoriale
  2. Caricare documenti nell'indice
  3. Eseguire una query sull'indice

Creare un indice vettoriale

Prima di aggiungere contenuto a Ricerca di intelligenza artificiale di Azure, è necessario creare un indice per definire la modalità di archiviazione e strutturazione del contenuto.

Lo schema dell'indice è organizzato in base al contenuto dell'hotel. I dati di esempio sono costituiti da descrizioni vettoriali e non vettoriali di hotel fittizi. Il codice seguente in createIndex.js crea lo schema dell'indice, incluso il campo DescriptionVectorvettoriale .

const searchFields = [
    { name: "HotelId", type: "Edm.String", key: true, sortable: true, filterable: true, facetable: true },
    { name: "HotelName", type: "Edm.String", searchable: true, filterable: true },
    { name: "Description", type: "Edm.String", searchable: true },
    {
        name: "DescriptionVector",
        type: "Collection(Edm.Single)",
        searchable: true,
        vectorSearchDimensions: 1536,
        vectorSearchProfileName: "vector-profile"
    },
    { name: "Category", type: "Edm.String", filterable: true, facetable: true },
    { name: "Tags", type: "Collection(Edm.String)", filterable: true },
    // Additional fields: ParkingIncluded, LastRenovationDate, Rating, Address, Location
];

const vectorSearch = {
    profiles: [
        {
            name: "vector-profile",
            algorithmConfigurationName: "vector-search-algorithm"
        }
    ],
    algorithms: [
        {
            name: "vector-search-algorithm",
            kind: "hnsw",
            parameters: { m: 4, efConstruction: 400, efSearch: 1000, metric: "cosine" }
        }
    ]
};

const semanticSearch = {
    configurations: [
        {
            name: "semantic-config",
            prioritizedFields: {
                contentFields: [{ name: "Description" }],
                keywordsFields: [{ name: "Category" }],
                titleField: { name: "HotelName" }
            }
        }
    ]
};

const searchIndex = {
    name: indexName,
    fields: searchFields,
    vectorSearch: vectorSearch,
    semanticSearch: semanticSearch,
    suggesters: [{ name: "sg", searchMode: "analyzingInfixMatching", sourceFields: ["HotelName"] }]
};

const result = await indexClient.createOrUpdateIndex(searchIndex);

Aspetti chiave:

  • Per definire un indice, creare un elenco di campi.

  • Questo particolare indice supporta più funzionalità di ricerca:

  • La vectorSearchDimensions proprietà deve corrispondere alle dimensioni di output del modello di incorporamento. Questo avvio rapido usa 1,536 dimensioni in corrispondenza al modello text-embedding-ada-002.

  • La configurazione di vectorSearch definisce l'algoritmo ANN (Approximate Nearest Neighbor). Gli algoritmi supportati includono HNSW (Hierarchical Navigable Small World) e KNN (K-Nearest Neighbor). Per altre informazioni, vedere Pertinenza nella ricerca vettoriale.

Caricare documenti nell'indice

Gli indici appena creati sono vuoti. Per popolare un indice e renderlo ricercabile, è necessario caricare documenti JSON conformi allo schema dell'indice.

In Ricerca di intelligenza artificiale di Azure i documenti fungono da input per l'indicizzazione e gli output per le query. Per semplicità, questa guida introduttiva fornisce documenti di hotel di esempio con vettori precompilate. Negli scenari di produzione, il contenuto viene spesso estratto da origini dati connesse e trasformato in JSON usando indicizzatori.

Il codice seguente in uploadDocuments.js carica i documenti nel servizio di ricerca.

const DOCUMENTS = [
    // Array of hotel documents with embedded 1536-dimension vectors
    // Each document contains: HotelId, HotelName, Description, DescriptionVector,
    // Category, Tags, ParkingIncluded, LastRenovationDate, Rating, Address, Location
];

const searchClient = new SearchClient(searchEndpoint, indexName, credential);

const result = await searchClient.uploadDocuments(DOCUMENTS);
for (const r of result.results) {
    console.log(`Key: ${r.key}, Succeeded: ${r.succeeded}`);
}

Il codice interagisce con un indice di ricerca specifico ospitato nel servizio Ricerca intelligenza artificiale di Azure tramite SearchClient, che è l'oggetto principale fornito dal @azure/search-documents pacchetto. SearchClient fornisce l'accesso alle operazioni sugli indici, ad esempio:

  • Inserimento dati: uploadDocuments, mergeDocuments, deleteDocuments

  • Operazioni di ricerca: search, autocomplete, suggest

Eseguire una query sull'indice

Le query nei file di ricerca illustrano modelli di ricerca diversi. Le query vettoriali di esempio si basano su due stringhe:

  • Stringa di ricerca full-text: "historic hotel walk to restaurants and shopping"

  • Stringa di query vettoriale: "quintessential lodging near running trails, eateries, retail" (vettorializzata in una rappresentazione matematica)

La stringa di query vettoriale è semanticamente simile alla stringa di ricerca full-text, ma include termini che non esistono nell'indice. Una ricerca di sola parola chiave per la stringa di query vettoriale restituisce zero risultati. Tuttavia, la ricerca vettoriale trova corrispondenze pertinenti in base al significato anziché alle parole chiave esatte.

Gli esempi seguenti iniziano con una query vettoriale di base e aggiungono progressivamente filtri, ricerca di parole chiave e reranking semantico.

searchSingle.js illustra uno scenario di base in cui si desidera trovare descrizioni di documenti che corrispondano strettamente alla stringa di query vettoriale. L'oggetto vectorQuery configura la ricerca vettoriale:

  • kNearestNeighborsCount limita il numero di risultati restituiti in base alla somiglianza del vettore.
  • fields specifica il campo vettoriale su cui eseguire la ricerca.
const vectorQuery = {
    vector: vector,
    kNearestNeighborsCount: 5,
    fields: ["DescriptionVector"],
    kind: "vector",
    exhaustive: true
};

const searchOptions = {
    top: 7,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"],
    includeTotalCount: true,
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const results = await searchClient.search("*", searchOptions);

for await (const result of results.results) {
    const doc = result.document;
    console.log(`HotelId: ${doc.HotelId}, HotelName: ${doc.HotelName}, Score: ${result.score}`);
}

Ricerca a vettore singolo con un filtro

In Ricerca di intelligenza artificiale di Azure i filtri si applicano ai campi non vettoriali in un indice. searchSingleWithFilter.js filtri sul Tags campo per filtrare tutti gli hotel che non forniscono wi-fi gratuito.

const searchOptions = {
    top: 7,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"],
    includeTotalCount: true,
    filter: "Tags/any(tag: tag eq 'free wifi')", // Adding filter for "free wifi" tag
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const results = await searchClient.search("*", searchOptions);

Ricerca a vettore singolo con un filtro geografico

È possibile specificare un filtro spaziale geografico per limitare i risultati a un'area geografica specifica. searchSingleWithGeoFilter.js specifica un punto geografico (Washington D.C., utilizzando coordinate di longitudine e latitudine) e restituisce gli hotel entro 300 chilometri. La filterMode proprietà determina quando viene eseguito il filtro. In questo caso, postFilter esegue il filtro dopo la ricerca vettoriale.

const searchOptions = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Category", "Description", "Address/City", "Address/StateProvince"],
    facets: ["Address/StateProvince"],
    filter: "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

La ricerca ibrida combina query full-text e vettoriali in una singola richiesta. searchHybrid.js esegue entrambi i tipi di query contemporaneamente e quindi usa La fusione tra rango reciproco (RRF) per unire i risultati in una classificazione unificata. RRF usa l'inverso delle classifiche dei risultati di ogni set di risultati per produrre una classifica unificata. Si noti che i punteggi di ricerca ibrida sono uniformemente inferiori ai punteggi di query singola.

const vectorQuery = {
    vector: vector,
    kNearestNeighborsCount: 5,
    fields: ["DescriptionVector"],
    kind: "vector",
    exhaustive: true
};

const searchOptions = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"],
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

// Use search text for keyword search (hybrid search = vector + keyword)
const searchText = "historic hotel walk to restaurants and shopping";
const results = await searchClient.search(searchText, searchOptions);

searchSemanticHybrid.js illustra la classificazione semantica, che classifica i risultati in base alla comprensione del linguaggio.

const searchOptions = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Category", "Description"],
    queryType: "semantic",
    semanticSearchOptions: {
        configurationName: "semantic-config"
    },
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const searchText = "historic hotel walk to restaurants and shopping";
const results = await searchClient.search(searchText, searchOptions);

for await (const result of results.results) {
    console.log(`Score: ${result.score}, Re-ranker Score: ${result.rerankerScore}`);
}

Confrontare questi risultati con i risultati della ricerca ibrida della query precedente. Senza reranking semantico, Sublime Palace Hotel si classifica primo perché la fusione di rango reciproco (RRF) combina il testo e i punteggi vettoriali per produrre un risultato combinato. Dopo il reranking semantico, Swirling Currents Hotel si sposta al primo posto.

Il ranker semantico usa modelli di comprensione automatica per valutare il livello di corrispondenza di ogni risultato con la finalità della query. La descrizione dell'Hotel Swirling Currents menziona "walking access to shopping, dining, entertainment and the city center", che è strettamente allineata con la ricerca "walk to restaurants and shopping". Questa corrispondenza di rilevanza semantica per ristoranti e negozi nelle vicinanze lo colloca al di sopra del Sublime Palace Hotel, che nella descrizione non mette in evidenza servizi raggiungibili a piedi.

Aspetti chiave:

  • In una ricerca ibrida è possibile integrare la ricerca vettoriale con la ricerca full-text sulle parole chiave. I filtri e la classificazione semantica si applicano solo al contenuto testuale, non ai vettori.

  • I risultati effettivi includono più dettagli, tra cui didascalie semantiche ed evidenziazioni. Questo avvio rapido modifica i risultati per la leggibilità. Per ottenere la struttura completa della risposta, usare REST per eseguire la richiesta.

Pulire le risorse

Quando si lavora nella propria sottoscrizione, è consigliabile completare un progetto rimuovendo le risorse non più necessarie. Le risorse lasciate in esecuzione possono avere un costo.

Nel portale di Azure selezionare Tutte le risorse o Gruppidi risorse nel riquadro sinistro per trovare e gestire le risorse. È possibile eliminare le risorse singolarmente o eliminare il gruppo di risorse per rimuovere tutte le risorse contemporaneamente.

In caso contrario, eseguire il comando seguente per eliminare l'indice creato in questa guida introduttiva.

node -r dotenv/config src/deleteIndex.js

In questa guida introduttiva si usa la libreria client di Ricerca intelligenza artificiale di Azure per JavaScript (compatibile con TypeScript) per creare, caricare ed eseguire query su un indice vettoriale. La libreria client JavaScript fornisce un'astrazione sulle API REST per le operazioni sugli indici.

In Ricerca di intelligenza artificiale di Azure, un indice vettoriale ha uno schema di indice che definisce i campi vettoriali e non vettoriali, una configurazione di ricerca vettoriale per gli algoritmi che creano lo spazio di embedding e le impostazioni delle definizioni dei campi vettoriali valutate in fase di query. Indici: crea o aggiorna (API REST) crea l'indice vettoriale.

Suggerimento

Prerequisiti

Configurare l'accesso

Prima di iniziare, assicurarsi di avere le autorizzazioni per accedere al contenuto e alle operazioni in Ricerca di intelligenza artificiale di Azure. Questa guida introduttiva utilizza Microsoft Entra ID per l'autenticazione e la gestione delle autorizzazioni basata sui ruoli. Per assegnare i ruoli, è necessario essere proprietario o amministratore accesso utenti . Se i ruoli non sono fattibili, usare invece l'autenticazione basata su chiave.

Per configurare l'accesso basato sui ruoli consigliato:

  1. Abilitare l'accesso in base al ruolo per il servizio di ricerca.

  2. Assegnare i ruoli seguenti all'account utente.

    • Collaboratore servizi di ricerca

    • Collaboratore ai dati dell'indice di ricerca

    • Lettore di dati dell'indice di ricerca

Ottenere l'endpoint

Ogni servizio ricerca di intelligenza artificiale di Azure ha un endpoint, ovvero un URL univoco che identifica e fornisce l'accesso alla rete al servizio. In una sezione successiva si specifica questo endpoint per connettersi al servizio di ricerca tramite programmazione.

Per ottenere l'endpoint:

  1. Accedere al portale di Azure e selezionare il servizio di ricerca.

  2. Nel riquadro sinistro selezionare Panoramica.

  3. Prendere nota dell'endpoint, che dovrebbe essere simile a https://my-service.search.windows.net.

Configurare l'ambiente

  1. Usare Git per clonare il repository di esempio.

    git clone https://github.com/Azure-Samples/azure-search-javascript-samples
    
  2. Passare alla cartella di avvio rapido e aprirla in Visual Studio Code.

    cd azure-search-javascript-samples/quickstart-vector-ts
    code .
    
  3. In sample.envsostituire il valore segnaposto per AZURE_SEARCH_ENDPOINT con l'URL ottenuto in Ottenere l'endpoint.

  4. Rinomina sample.env in .env.

    mv sample.env .env
    
  5. Installa le dipendenze.

    npm install
    

    Al termine dell'installazione, verrà visualizzata una node_modules cartella nella directory del progetto.

  6. Per l'autenticazione senza chiave con Microsoft Entra ID, accedere all'account Azure. Se si hanno più sottoscrizioni, selezionare quella che contiene il servizio Ricerca intelligenza artificiale di Azure.

    az login
    

Eseguire il codice

  1. Creare un indice vettoriale.

    npm run build && node -r dotenv/config dist/createIndex.js
    
  2. Caricare documenti contenenti incorporamenti precompilate.

    npm run build && node -r dotenv/config dist/uploadDocuments.js
    
  3. Eseguire una query di ricerca vettoriale.

    npm run build && node -r dotenv/config dist/searchSingle.js
    
  4. (Facoltativo) Eseguire varianti di query aggiuntive.

    npm run build && node -r dotenv/config dist/searchSingleWithFilter.js
    npm run build && node -r dotenv/config dist/searchSingleWithFilterGeo.js
    npm run build && node -r dotenv/config dist/searchHybrid.js
    npm run build && node -r dotenv/config dist/searchSemanticHybrid.js
    

Annotazioni

Il comando npm run build compila i file TypeScript presenti in src/ trasformandoli in JavaScript in dist/.

Risultato

L'output di createIndex.ts mostra il nome e la conferma dell'indice.

Using Azure Search endpoint: https://<search-service-name>.search.windows.net
Using index name: hotels-vector-quickstart
Creating index...
hotels-vector-quickstart created

L'output di uploadDocuments.ts mostra lo stato di successo per ogni documento indicizzato.

Uploading documents...
Key: 1, Succeeded: true, ErrorMessage: none
Key: 2, Succeeded: true, ErrorMessage: none
Key: 3, Succeeded: true, ErrorMessage: none
Key: 4, Succeeded: true, ErrorMessage: none
Key: 48, Succeeded: true, ErrorMessage: none
Key: 49, Succeeded: true, ErrorMessage: none
Key: 13, Succeeded: true, ErrorMessage: none
All documents indexed successfully.

L'output di mostra i risultati della searchSingle.ts ricerca vettoriale classificati in base al punteggio di somiglianza.

Single Vector search found 5
- HotelId: 48, HotelName: Nordick's Valley Motel, Tags: ["continental breakfast","air conditioning","free wifi"], Score 0.6605852
- HotelId: 13, HotelName: Luxury Lion Resort, Tags: ["bar","concierge","restaurant"], Score 0.6333684
- HotelId: 4, HotelName: Sublime Palace Hotel, Tags: ["concierge","view","air conditioning"], Score 0.605672
- HotelId: 49, HotelName: Swirling Currents Hotel, Tags: ["air conditioning","laundry service","24-hour front desk service"], Score 0.6026341
- HotelId: 2, HotelName: Old Century Hotel, Tags: ["pool","free wifi","air conditioning","concierge"], Score 0.57902366

Informazioni sul codice

Annotazioni

I frammenti di codice in questa sezione potrebbero essere stati modificati per la leggibilità. Per un esempio funzionante completo, vedere il codice sorgente.

Dopo aver eseguito il codice, è possibile suddividere i passaggi principali:

  1. Creare un indice vettoriale
  2. Caricare documenti nell'indice
  3. Eseguire una query sull'indice

Creare un indice vettoriale

Prima di aggiungere contenuto a Ricerca di intelligenza artificiale di Azure, è necessario creare un indice per definire la modalità di archiviazione e strutturazione del contenuto.

Lo schema dell'indice è organizzato in base al contenuto dell'hotel. I dati di esempio sono costituiti da descrizioni vettoriali e non vettoriali di hotel fittizi. Il codice seguente in createIndex.ts crea lo schema dell'indice, incluso il campo DescriptionVectorvettoriale .

const searchFields: SearchField[] = [
    { name: "HotelId", type: "Edm.String", key: true, sortable: true, filterable: true, facetable: true },
    { name: "HotelName", type: "Edm.String", searchable: true, filterable: true },
    { name: "Description", type: "Edm.String", searchable: true },
    {
        name: "DescriptionVector",
        type: "Collection(Edm.Single)",
        searchable: true,
        vectorSearchDimensions: 1536,
        vectorSearchProfileName: "vector-profile"
    },
    { name: "Category", type: "Edm.String", filterable: true, facetable: true },
    { name: "Tags", type: "Collection(Edm.String)", filterable: true },
    // Additional fields: ParkingIncluded, LastRenovationDate, Rating, Address, Location
];

const vectorSearch: VectorSearch = {
    profiles: [
        {
            name: "vector-profile",
            algorithmConfigurationName: "vector-search-algorithm"
        }
    ],
    algorithms: [
        {
            name: "vector-search-algorithm",
            kind: "hnsw",
            parameters: { m: 4, efConstruction: 400, efSearch: 1000, metric: "cosine" }
        }
    ]
};

const semanticSearch: SemanticSearch = {
    configurations: [
        {
            name: "semantic-config",
            prioritizedFields: {
                contentFields: [{ name: "Description" }],
                keywordsFields: [{ name: "Category" }],
                titleField: { name: "HotelName" }
            }
        }
    ]
};

const searchIndex: SearchIndex = {
    name: indexName,
    fields: searchFields,
    vectorSearch: vectorSearch,
    semanticSearch: semanticSearch,
    suggesters: [{ name: "sg", searchMode: "analyzingInfixMatching", sourceFields: ["HotelName"] }]
};

const result = await indexClient.createOrUpdateIndex(searchIndex);

Aspetti chiave:

  • Per definire un indice, creare un elenco di campi.

  • Questo particolare indice supporta più funzionalità di ricerca:

  • La vectorSearchDimensions proprietà deve corrispondere alle dimensioni di output del modello di incorporamento. Questo avvio rapido usa 1,536 dimensioni in corrispondenza al modello text-embedding-ada-002.

  • La configurazione di vectorSearch definisce l'algoritmo ANN (Approximate Nearest Neighbor). Gli algoritmi supportati includono HNSW (Hierarchical Navigable Small World) e KNN (K-Nearest Neighbor). Per altre informazioni, vedere Pertinenza nella ricerca vettoriale.

Caricare documenti nell'indice

Gli indici appena creati sono vuoti. Per popolare un indice e renderlo ricercabile, è necessario caricare documenti JSON conformi allo schema dell'indice.

In Ricerca di intelligenza artificiale di Azure i documenti fungono da input per l'indicizzazione e gli output per le query. Per semplicità, questa guida introduttiva fornisce documenti di hotel di esempio con vettori precompilate. Negli scenari di produzione, il contenuto viene spesso estratto da origini dati connesse e trasformato in JSON usando indicizzatori.

Il codice seguente in uploadDocuments.ts carica i documenti nel servizio di ricerca.

const DOCUMENTS = [
    // Array of hotel documents with embedded 1536-dimension vectors
    // Each document contains: HotelId, HotelName, Description, DescriptionVector,
    // Category, Tags, ParkingIncluded, LastRenovationDate, Rating, Address, Location
];

const searchClient = new SearchClient(searchEndpoint, indexName, credential);

const result = await searchClient.uploadDocuments(DOCUMENTS);
for (const r of result.results) {
    console.log(`Key: ${r.key}, Succeeded: ${r.succeeded}`);
}

Il codice interagisce con un indice di ricerca specifico ospitato nel servizio Ricerca intelligenza artificiale di Azure tramite SearchClient, che è l'oggetto principale fornito dal @azure/search-documents pacchetto. SearchClient fornisce l'accesso alle operazioni sugli indici, ad esempio:

  • Inserimento dati: uploadDocuments, mergeDocuments, deleteDocuments

  • Operazioni di ricerca: search, autocomplete, suggest

Eseguire una query sull'indice

Le query nei file di ricerca illustrano modelli di ricerca diversi. Le query vettoriali di esempio si basano su due stringhe:

  • Stringa di ricerca full-text: "historic hotel walk to restaurants and shopping"

  • Stringa di query vettoriale: "quintessential lodging near running trails, eateries, retail" (vettorializzata in una rappresentazione matematica)

La stringa di query vettoriale è semanticamente simile alla stringa di ricerca full-text, ma include termini che non esistono nell'indice. Una ricerca di sola parola chiave per la stringa di query vettoriale restituisce zero risultati. Tuttavia, la ricerca vettoriale trova corrispondenze pertinenti in base al significato anziché alle parole chiave esatte.

Gli esempi seguenti iniziano con una query vettoriale di base e aggiungono progressivamente filtri, ricerca di parole chiave e reranking semantico.

searchSingle.ts illustra uno scenario di base in cui si desidera trovare descrizioni di documenti che corrispondano strettamente alla stringa di query vettoriale. L'oggetto VectorQuery configura la ricerca vettoriale:

  • kNearestNeighborsCount limita il numero di risultati restituiti in base alla somiglianza del vettore.
  • fields specifica il campo vettoriale su cui eseguire la ricerca.
const vectorQuery: VectorQuery<HotelDocument> = {
    vector: vector,
    kNearestNeighborsCount: 5,
    fields: ["DescriptionVector"],
    kind: "vector",
    exhaustive: true
};

const searchOptions: SearchOptions<HotelDocument> = {
    top: 7,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"] as const,
    includeTotalCount: true,
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const results: SearchDocumentsResult<HotelDocument> = await searchClient.search("*", searchOptions);

for await (const result of results.results) {
    const doc = result.document;
    console.log(`HotelId: ${doc.HotelId}, HotelName: ${doc.HotelName}, Score: ${result.score}`);
}

Ricerca a vettore singolo con un filtro

In Ricerca di intelligenza artificiale di Azure i filtri si applicano ai campi non vettoriali in un indice. searchSingleWithFilter.ts filtri sul Tags campo per filtrare tutti gli hotel che non forniscono wi-fi gratuito.

const searchOptions: SearchOptions<HotelDocument> = {
    top: 7,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"] as const,
    includeTotalCount: true,
    filter: "Tags/any(tag: tag eq 'free wifi')", // Adding filter for "free wifi" tag
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const results: SearchDocumentsResult<HotelDocument> = await searchClient.search("*", searchOptions);

Ricerca a vettore singolo con un filtro geografico

È possibile specificare un filtro spaziale geografico per limitare i risultati a un'area geografica specifica. searchSingleWithGeoFilter.ts specifica un punto geografico (Washington D.C., utilizzando coordinate di longitudine e latitudine) e restituisce gli hotel entro 300 chilometri. La filterMode proprietà determina quando viene eseguito il filtro. In questo caso, postFilter esegue il filtro dopo la ricerca vettoriale.

const searchOptions: SearchOptions<HotelDocument> = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Category", "Description", "Address/City", "Address/StateProvince"] as const,
    facets: ["Address/StateProvince"],
    filter: "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

La ricerca ibrida combina query full-text e vettoriali in una singola richiesta. searchHybrid.ts esegue entrambi i tipi di query contemporaneamente e quindi usa La fusione tra rango reciproco (RRF) per unire i risultati in una classificazione unificata. RRF usa l'inverso delle classifiche dei risultati di ogni set di risultati per produrre una classifica unificata. Si noti che i punteggi di ricerca ibrida sono uniformemente inferiori ai punteggi di query singola.

const vectorQuery: VectorQuery<HotelDocument> = {
    vector: vector,
    kNearestNeighborsCount: 5,
    fields: ["DescriptionVector"],
    kind: "vector",
    exhaustive: true
};

const searchOptions: SearchOptions<HotelDocument> = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Description", "Category", "Tags"] as const,
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

// Use search text for keyword search (hybrid search = vector + keyword)
const searchText = "historic hotel walk to restaurants and shopping";
const results: SearchDocumentsResult<HotelDocument> = await searchClient.search(searchText, searchOptions);

searchSemanticHybrid.ts illustra la classificazione semantica, che classifica i risultati in base alla comprensione del linguaggio.

const searchOptions: SearchOptions<HotelDocument> = {
    top: 5,
    includeTotalCount: true,
    select: ["HotelId", "HotelName", "Category", "Description"] as const,
    queryType: "semantic" as const,
    semanticSearchOptions: {
        configurationName: "semantic-config"
    },
    vectorSearchOptions: {
        queries: [vectorQuery],
        filterMode: "postFilter"
    }
};

const searchText = "historic hotel walk to restaurants and shopping";
const results: SearchDocumentsResult<HotelDocument> = await searchClient.search(searchText, searchOptions);

for await (const result of results.results) {
    console.log(`Score: ${result.score}, Re-ranker Score: ${result.rerankerScore}`);
}

Confrontare questi risultati con i risultati della ricerca ibrida della query precedente. Senza reranking semantico, Sublime Palace Hotel si classifica primo perché la fusione di rango reciproco (RRF) combina il testo e i punteggi vettoriali per produrre un risultato combinato. Dopo il reranking semantico, Swirling Currents Hotel si sposta al primo posto.

Il ranker semantico usa modelli di comprensione automatica per valutare il livello di corrispondenza di ogni risultato con la finalità della query. La descrizione dell'Hotel Swirling Currents menziona "walking access to shopping, dining, entertainment and the city center", che è strettamente allineata con la ricerca "walk to restaurants and shopping". Questa corrispondenza di rilevanza semantica per ristoranti e negozi nelle vicinanze lo colloca al di sopra del Sublime Palace Hotel, che nella descrizione non mette in evidenza servizi raggiungibili a piedi.

Aspetti chiave:

  • In una ricerca ibrida è possibile integrare la ricerca vettoriale con la ricerca full-text sulle parole chiave. I filtri e la classificazione semantica si applicano solo al contenuto testuale, non ai vettori.

  • I risultati effettivi includono più dettagli, tra cui didascalie semantiche ed evidenziazioni. Questo avvio rapido modifica i risultati per la leggibilità. Per ottenere la struttura completa della risposta, usare REST per eseguire la richiesta.

Pulire le risorse

Quando si lavora nella propria sottoscrizione, è consigliabile completare un progetto rimuovendo le risorse non più necessarie. Le risorse lasciate in esecuzione possono avere un costo.

Nel portale di Azure selezionare Tutte le risorse o Gruppidi risorse nel riquadro sinistro per trovare e gestire le risorse. È possibile eliminare le risorse singolarmente o eliminare il gruppo di risorse per rimuovere tutte le risorse contemporaneamente.

In caso contrario, eseguire il comando seguente per eliminare l'indice creato in questa guida introduttiva.

npm run build && node -r dotenv/config dist/deleteIndex.js

In questa guida introduttiva, si utilizza la libreria client Azure AI Search per .NET per creare, caricare ed eseguire query su un indice vettoriale. La libreria client .NET fornisce un'astrazione sulle API REST per le operazioni sugli indici.

In Ricerca di intelligenza artificiale di Azure, un indice vettoriale ha uno schema di indice che definisce i campi vettoriali e non vettoriali, una configurazione di ricerca vettoriale per gli algoritmi che creano lo spazio di embedding e le impostazioni delle definizioni dei campi vettoriali valutate in fase di query. Indici: crea o aggiorna (API REST) crea l'indice vettoriale.

Suggerimento

Prerequisiti

Configurare l'accesso

Prima di iniziare, assicurarsi di avere le autorizzazioni per accedere al contenuto e alle operazioni in Ricerca di intelligenza artificiale di Azure. Questa guida introduttiva utilizza Microsoft Entra ID per l'autenticazione e la gestione delle autorizzazioni basata sui ruoli. Per assegnare i ruoli, è necessario essere proprietario o amministratore accesso utenti . Se i ruoli non sono fattibili, usare invece l'autenticazione basata su chiave.

Per configurare l'accesso basato sui ruoli consigliato:

  1. Abilitare l'accesso in base al ruolo per il servizio di ricerca.

  2. Assegnare i ruoli seguenti all'account utente.

    • Collaboratore servizi di ricerca

    • Collaboratore ai dati dell'indice di ricerca

    • Lettore di dati dell'indice di ricerca

Ottenere l'endpoint

Ogni servizio ricerca di intelligenza artificiale di Azure ha un endpoint, ovvero un URL univoco che identifica e fornisce l'accesso alla rete al servizio. In una sezione successiva si specifica questo endpoint per connettersi al servizio di ricerca tramite programmazione.

Per ottenere l'endpoint:

  1. Accedere al portale di Azure e selezionare il servizio di ricerca.

  2. Nel riquadro sinistro selezionare Panoramica.

  3. Prendere nota dell'endpoint, che dovrebbe essere simile a https://my-service.search.windows.net.

Configurare l'ambiente

  1. Usare Git per clonare il repository di esempio.

    git clone https://github.com/Azure-Samples/azure-search-dotnet-samples
    
  2. Passare alla cartella di avvio rapido e aprirla in Visual Studio Code.

    cd azure-search-dotnet-samples/quickstart-vector-search
    code .
    
  3. In VectorSearchCreatePopulateIndex/appsettings.jsonsostituire il valore segnaposto per Endpoint con l'URL ottenuto in Ottenere l'endpoint.

  4. Ripetere il passaggio precedente per VectorSearchExamples/appsettings.json.

  5. Per l'autenticazione senza chiave con Microsoft Entra ID, accedere all'account Azure. Se si hanno più sottoscrizioni, selezionare quella che contiene il servizio Ricerca intelligenza artificiale di Azure.

    az login
    

Eseguire il codice

  1. Eseguire il primo progetto per creare e popolare l'indice.

    cd VectorSearchCreatePopulateIndex
    dotnet run
    
  2. In VectorSearchExamples/Program.cs rimuovere il commento dai metodi di query che si vuole eseguire.

  3. Eseguire il secondo progetto per eseguire tali query sull'indice.

    cd ..\VectorSearchExamples
    dotnet run
    

Risultato

L'output del primo progetto include la conferma della creazione dell'indice e il corretto caricamento dei documenti.

Creating or updating index 'hotels-vector-quickstart'...
Index 'hotels-vector-quickstart' updated.

Key: 1, Succeeded: True
Key: 2, Succeeded: True
Key: 3, Succeeded: True
Key: 4, Succeeded: True
Key: 48, Succeeded: True
Key: 49, Succeeded: True
Key: 13, Succeeded: True

L'output del secondo progetto mostra i risultati della ricerca per ogni metodo di query abilitato. L'esempio seguente mostra i risultati della ricerca a vettore singolo.

Single Vector Search Results:
Score: 0.6605852, HotelId: 48, HotelName: Nordick's Valley Motel
Score: 0.6333684, HotelId: 13, HotelName: Luxury Lion Resort
Score: 0.605672, HotelId: 4, HotelName: Sublime Palace Hotel
Score: 0.6026341, HotelId: 49, HotelName: Swirling Currents Hotel
Score: 0.57902366, HotelId: 2, HotelName: Old Century Hotel

Informazioni sul codice

Annotazioni

I frammenti di codice in questa sezione potrebbero essere stati modificati per la leggibilità. Per un esempio funzionante completo, vedere il codice sorgente.

Dopo aver eseguito il codice, è possibile suddividere i passaggi principali:

  1. Creare un indice vettoriale
  2. Caricare documenti nell'indice
  3. Eseguire una query sull'indice

Creare un indice vettoriale

Prima di aggiungere contenuto a Ricerca di intelligenza artificiale di Azure, è necessario creare un indice per definire la modalità di archiviazione e strutturazione del contenuto.

Lo schema dell'indice è organizzato in base al contenuto dell'hotel. I dati di esempio sono costituiti da descrizioni vettoriali e non vettoriali di hotel fittizi. Il codice seguente in VectorSearchCreatePopulateIndex/Program.cs crea lo schema dell'indice, incluso il campo DescriptionVectorvettoriale .

static async Task CreateSearchIndex(string indexName, SearchIndexClient indexClient)
{
    var addressField = new ComplexField("Address");
    addressField.Fields.Add(new SearchableField("StreetAddress") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft });
    addressField.Fields.Add(new SearchableField("City") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true });
    addressField.Fields.Add(new SearchableField("StateProvince") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true });
    addressField.Fields.Add(new SearchableField("PostalCode") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true });
    addressField.Fields.Add(new SearchableField("Country") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true });

    var allFields = new List<SearchField>()
    {
        new SimpleField("HotelId", SearchFieldDataType.String) { IsKey = true, IsFacetable = true, IsFilterable = true },
        new SearchableField("HotelName") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft },
        new SearchableField("Description") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft },
        new VectorSearchField("DescriptionVector", 1536, "my-vector-profile"),
        new SearchableField("Category") { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true },
        new SearchableField("Tags", collection: true) { AnalyzerName = LexicalAnalyzerName.EnMicrosoft, IsFacetable = true, IsFilterable = true },
        new SimpleField("ParkingIncluded", SearchFieldDataType.Boolean) { IsFacetable = true, IsFilterable = true },
        new SimpleField("LastRenovationDate", SearchFieldDataType.DateTimeOffset) { IsSortable = true },
        new SimpleField("Rating", SearchFieldDataType.Double) { IsFacetable = true, IsFilterable = true, IsSortable = true },
        addressField,
        new SimpleField("Location", SearchFieldDataType.GeographyPoint) { IsFilterable = true, IsSortable = true },
    };

    // Create the suggester configuration
    var suggester = new SearchSuggester("sg", new[] { "Address/City", "Address/Country" });

    // Create the semantic search
    var semanticSearch = new SemanticSearch()
    {
        Configurations =
        {
            new SemanticConfiguration(
                name: "semantic-config",
                prioritizedFields: new SemanticPrioritizedFields
                {
                    TitleField = new SemanticField("HotelName"),
                    KeywordsFields = { new SemanticField("Category") },
                    ContentFields = { new SemanticField("Description") }
                })
        }
    };

    // Add vector search configuration
    var vectorSearch = new VectorSearch();
    vectorSearch.Algorithms.Add(new HnswAlgorithmConfiguration(name: "my-hnsw-vector-config-1"));
    vectorSearch.Profiles.Add(new VectorSearchProfile(name: "my-vector-profile", algorithmConfigurationName: "my-hnsw-vector-config-1"));

    var definition = new SearchIndex(indexName)
    {
        Fields = allFields,
        Suggesters = { suggester },
        VectorSearch = vectorSearch,
        SemanticSearch = semanticSearch
    };

    // Create or update the index
    Console.WriteLine($"Creating or updating index '{indexName}'...");
    var result = await indexClient.CreateOrUpdateIndexAsync(definition);
    Console.WriteLine($"Index '{result.Value.Name}' updated.");
    Console.WriteLine();
}

Aspetti chiave:

  • Per definire un indice, creare un elenco di campi.

  • Questo particolare indice supporta più funzionalità di ricerca:

  • Il secondo parametro in VectorSearchField specifica vectorSearchDimensions, che deve corrispondere alle dimensioni di output del modello di incorporamento. Questo avvio rapido usa 1,536 dimensioni in corrispondenza al modello text-embedding-ada-002.

  • La configurazione di VectorSearch definisce l'algoritmo ANN (Approximate Nearest Neighbor). Gli algoritmi supportati includono HNSW (Hierarchical Navigable Small World) e KNN (K-Nearest Neighbor). Per altre informazioni, vedere Pertinenza nella ricerca vettoriale.

Caricare documenti nell'indice

Gli indici appena creati sono vuoti. Per popolare un indice e renderlo ricercabile, è necessario caricare documenti JSON conformi allo schema dell'indice.

In Ricerca di intelligenza artificiale di Azure i documenti fungono da input per l'indicizzazione e gli output per le query. Per semplicità, questa guida introduttiva fornisce documenti di hotel di esempio con vettori precompilate. Negli scenari di produzione, il contenuto viene spesso estratto da origini dati connesse e trasformato in JSON usando indicizzatori.

Il codice seguente carica i documenti da HotelData.json al vostro servizio di ricerca.

static async Task UploadDocs(SearchClient searchClient)
{
    var jsonPath = Path.Combine(Directory.GetCurrentDirectory(), "HotelData.json");

    // Read and parse hotel data
    var json = await File.ReadAllTextAsync(jsonPath);
    List<Hotel> hotels = new List<Hotel>();
    try
    {
        using var doc = JsonDocument.Parse(json);
        if (doc.RootElement.ValueKind != JsonValueKind.Array)
        {
            Console.WriteLine("HotelData.json root is not a JSON array.");
        }
        // Deserialize all hotel objects
        hotels = doc.RootElement.EnumerateArray()
            .Select(e => JsonSerializer.Deserialize<Hotel>(e.GetRawText()))
            .Where(h => h != null)
            .ToList();
    }
    catch (JsonException ex)
    {
        Console.WriteLine($"Failed to parse HotelData.json: {ex.Message}");
    }

    try
    {
        // Upload hotel documents to Azure Search
        var result = await searchClient.UploadDocumentsAsync(hotels);
        foreach (var r in result.Value.Results)
        {
            Console.WriteLine($"Key: {r.Key}, Succeeded: {r.Succeeded}");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Failed to upload documents: " + ex);
    }
}

Il codice interagisce con un indice di ricerca specifico ospitato nel servizio Ricerca intelligenza artificiale di Azure tramite SearchClient, che è l'oggetto principale fornito dal Azure.Search.Documents pacchetto. SearchClient fornisce l'accesso alle operazioni sugli indici, ad esempio:

  • Inserimento dati: UploadDocuments(), MergeDocuments(), DeleteDocuments()

  • Operazioni di ricerca: Search(), Autocomplete(), Suggest()

Eseguire una query sull'indice

Le query in VectorSearchExamples illustrano modelli di ricerca diversi. Le query vettoriali di esempio si basano su due stringhe:

  • Stringa di ricerca full-text: "historic hotel walk to restaurants and shopping"

  • Stringa di query vettoriale: "quintessential lodging near running trails, eateries, retail" (vettorializzata in una rappresentazione matematica)

La stringa di query vettoriale è semanticamente simile alla stringa di ricerca full-text, ma include termini che non esistono nell'indice. Una ricerca di sola parola chiave per la stringa di query vettoriale restituisce zero risultati. Tuttavia, la ricerca vettoriale trova corrispondenze pertinenti in base al significato anziché alle parole chiave esatte.

Gli esempi seguenti iniziano con una query vettoriale di base e aggiungono progressivamente filtri, ricerca di parole chiave e reranking semantico.

Il SearchSingleVector metodo illustra uno scenario di base in cui si desidera trovare descrizioni di documenti che corrispondano strettamente alla stringa di query vettoriale. VectorizedQuery configura la ricerca vettoriale:

  • KNearestNeighborsCount limita il numero di risultati restituiti in base alla somiglianza del vettore.
  • Fields specifica il campo vettoriale su cui eseguire la ricerca.
public static async Task SearchSingleVector(SearchClient searchClient, ReadOnlyMemory<float> precalculatedVector)
{
    SearchResults<Hotel> response = await searchClient.SearchAsync<Hotel>(
        new SearchOptions
        {
            VectorSearch = new()
            {
                Queries = { new VectorizedQuery(precalculatedVector) { KNearestNeighborsCount = 5, Fields = { "DescriptionVector" } } }
            },
            Select = { "HotelId", "HotelName", "Description", "Category", "Tags" },
        });

    Console.WriteLine($"Single Vector Search Results:");
    await foreach (SearchResult<Hotel> result in response.GetResultsAsync())
    {
        Hotel doc = result.Document;
        Console.WriteLine($"Score: {result.Score}, HotelId: {doc.HotelId}, HotelName: {doc.HotelName}");
    }
    Console.WriteLine();
}

Ricerca a vettore singolo con un filtro

In Ricerca di intelligenza artificiale di Azure i filtri si applicano ai campi non vettoriali in un indice. Il SearchSingleVectorWithFilter metodo filtra sul Tags campo per filtrare tutti gli hotel che non forniscono wi-fi gratuito.

public static async Task SearchSingleVectorWithFilter(SearchClient searchClient, ReadOnlyMemory<float> precalculatedVector)
{
    SearchResults<Hotel> responseWithFilter = await searchClient.SearchAsync<Hotel>(
        new SearchOptions
        {
            VectorSearch = new()
            {
                Queries = { new VectorizedQuery(precalculatedVector) { KNearestNeighborsCount = 5, Fields = { "DescriptionVector" } } }
            },
            Filter = "Tags/any(tag: tag eq 'free wifi')",
            Select = { "HotelId", "HotelName", "Description", "Category", "Tags" }
        });

    Console.WriteLine($"Single Vector Search With Filter Results:");
    await foreach (SearchResult<Hotel> result in responseWithFilter.GetResultsAsync())
    {
        Hotel doc = result.Document;
        Console.WriteLine($"Score: {result.Score}, HotelId: {doc.HotelId}, HotelName: {doc.HotelName}, Tags: {string.Join(String.Empty, doc.Tags)}");
    }
    Console.WriteLine();
}

Ricerca a vettore singolo con un filtro geografico

È possibile specificare un filtro spaziale geografico per limitare i risultati a un'area geografica specifica. Il SingleSearchWithGeoFilter metodo specifica un punto geografico (Washington D.C., utilizzando coordinate di longitudine e latitudine) e restituisce gli hotel entro 300 chilometri. Per impostazione predefinita, i filtri vengono eseguiti dopo la ricerca vettoriale.

public static async Task SingleSearchWithGeoFilter(SearchClient searchClient, ReadOnlyMemory<float> precalculatedVector)
{
    SearchResults<Hotel> responseWithGeoFilter = await searchClient.SearchAsync<Hotel>(
        new SearchOptions
        {
            VectorSearch = new()
            {
                Queries = { new VectorizedQuery(precalculatedVector) { KNearestNeighborsCount = 5, Fields = { "DescriptionVector" } } }
            },
            Filter = "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",
            Select = { "HotelId", "HotelName", "Description", "Address", "Category", "Tags" },
            Facets = { "Address/StateProvince" },
        });

    Console.WriteLine($"Vector query with a geo filter:");
    await foreach (SearchResult<Hotel> result in responseWithGeoFilter.GetResultsAsync())
    {
        Hotel doc = result.Document;
        Console.WriteLine($"HotelId: {doc.HotelId}");
        Console.WriteLine($"HotelName: {doc.HotelName}");
        Console.WriteLine($"Score: {result.Score}");
        Console.WriteLine($"City/State: {doc.Address.City}/{doc.Address.StateProvince}");
        Console.WriteLine($"Description: {doc.Description}");
        Console.WriteLine();
    }
    Console.WriteLine();
}

La ricerca ibrida combina query full-text e vettoriali in una singola richiesta. Il SearchHybridVectorAndText metodo esegue simultaneamente entrambi i tipi di query e quindi usa La fusione di rango reciproco (RRF) per unire i risultati in una classificazione unificata. RRF usa l'inverso delle classifiche dei risultati di ogni set di risultati per produrre una classifica unificata. Si noti che i punteggi di ricerca ibrida sono uniformemente inferiori ai punteggi di query singola.

public static async Task<SearchResults<Hotel>> SearchHybridVectorAndText(SearchClient searchClient, ReadOnlyMemory<float> precalculatedVector)
{
    SearchResults<Hotel> responseWithFilter = await searchClient.SearchAsync<Hotel>(
        "historic hotel walk to restaurants and shopping",
        new SearchOptions
        {
            VectorSearch = new()
            {
                Queries = { new VectorizedQuery(precalculatedVector) { KNearestNeighborsCount = 5, Fields = { "DescriptionVector" } } }
            },
            Select = { "HotelId", "HotelName", "Description", "Category", "Tags" },
            Size = 5,
        });

    Console.WriteLine($"Hybrid search results:");
    await foreach (SearchResult<Hotel> result in responseWithFilter.GetResultsAsync())
    {
        Hotel doc = result.Document;
        Console.WriteLine($"Score: {result.Score}");
        Console.WriteLine($"HotelId: {doc.HotelId}");
        Console.WriteLine($"HotelName: {doc.HotelName}");
        Console.WriteLine($"Description: {doc.Description}");
        Console.WriteLine($"Category: {doc.Category}");
        Console.WriteLine($"Tags: {string.Join(String.Empty, doc.Tags)}");
        Console.WriteLine();
    }
    Console.WriteLine();
    return responseWithFilter;
}

Il SearchHybridVectorAndSemantic metodo illustra la classificazione semantica, che classifica i risultati in base alla comprensione del linguaggio.

public static async Task SearchHybridVectorAndSemantic(SearchClient searchClient, ReadOnlyMemory<float> precalculatedVector)
{
    SearchResults<Hotel> responseWithFilter = await searchClient.SearchAsync<Hotel>(
        "historic hotel walk to restaurants and shopping",
        new SearchOptions
        {
            IncludeTotalCount = true,
            VectorSearch = new()
            {
                Queries = { new VectorizedQuery(precalculatedVector) { KNearestNeighborsCount = 5, Fields = { "DescriptionVector" } } }
            },
            Select = { "HotelId", "HotelName", "Description", "Category", "Tags" },
            SemanticSearch = new SemanticSearchOptions
            {
                SemanticConfigurationName = "semantic-config"
            },
            QueryType = SearchQueryType.Semantic,
            Size = 5
        });

    Console.WriteLine($"Hybrid search results:");
    await foreach (SearchResult<Hotel> result in responseWithFilter.GetResultsAsync())
    {
        Hotel doc = result.Document;
        Console.WriteLine($"Score: {result.Score}");
        Console.WriteLine($"HotelId: {doc.HotelId}");
        Console.WriteLine($"HotelName: {doc.HotelName}");
        Console.WriteLine($"Description: {doc.Description}");
        Console.WriteLine($"Category: {doc.Category}");
        Console.WriteLine();
    }
    Console.WriteLine();
}

Confrontare questi risultati con i risultati della ricerca ibrida della query precedente. Senza reranking semantico, Sublime Palace Hotel si classifica primo perché la fusione di rango reciproco (RRF) combina il testo e i punteggi vettoriali per produrre un risultato combinato. Dopo il reranking semantico, Swirling Currents Hotel si sposta al primo posto.

Il ranker semantico usa modelli di comprensione automatica per valutare il livello di corrispondenza di ogni risultato con la finalità della query. La descrizione dell'Hotel Swirling Currents menziona "walking access to shopping, dining, entertainment and the city center", che è strettamente allineata con la ricerca "walk to restaurants and shopping". Questa corrispondenza di rilevanza semantica per ristoranti e negozi nelle vicinanze lo colloca al di sopra del Sublime Palace Hotel, che nella descrizione non mette in evidenza servizi raggiungibili a piedi.

Aspetti chiave:

  • In una ricerca ibrida è possibile integrare la ricerca vettoriale con la ricerca full-text sulle parole chiave. I filtri e la classificazione semantica si applicano solo al contenuto testuale, non ai vettori.

  • I risultati effettivi includono più dettagli, tra cui didascalie semantiche ed evidenziazioni. Questo avvio rapido modifica i risultati per la leggibilità. Per ottenere la struttura completa della risposta, usare REST per eseguire la richiesta.

Pulire le risorse

Quando si lavora nella propria sottoscrizione, è consigliabile completare un progetto rimuovendo le risorse non più necessarie. Le risorse lasciate in esecuzione possono avere un costo.

Nel portale di Azure selezionare Tutte le risorse o Gruppidi risorse nel riquadro sinistro per trovare e gestire le risorse. È possibile eliminare le risorse singolarmente o eliminare il gruppo di risorse per rimuovere tutte le risorse contemporaneamente.

In questa guida introduttiva si usano le API REST di Ricerca intelligenza artificiale di Azure per creare, caricare ed eseguire query su un indice vettoriale.

In Ricerca di intelligenza artificiale di Azure, un indice vettoriale ha uno schema di indice che definisce i campi vettoriali e non vettoriali, una configurazione di ricerca vettoriale per gli algoritmi che creano lo spazio di embedding e le impostazioni delle definizioni dei campi vettoriali valutate in fase di query. Indici: crea o aggiorna (API REST) crea l'indice vettoriale.

Suggerimento

Prerequisiti

Configurare l'accesso

Prima di iniziare, assicurarsi di avere le autorizzazioni per accedere al contenuto e alle operazioni in Ricerca di intelligenza artificiale di Azure. Questa guida introduttiva utilizza Microsoft Entra ID per l'autenticazione e la gestione delle autorizzazioni basata sui ruoli. Per assegnare i ruoli, è necessario essere proprietario o amministratore accesso utenti . Se i ruoli non sono fattibili, usare invece l'autenticazione basata su chiave.

Per configurare l'accesso basato sui ruoli consigliato:

  1. Abilitare l'accesso in base al ruolo per il servizio di ricerca.

  2. Assegnare i ruoli seguenti all'account utente.

    • Collaboratore servizi di ricerca

    • Collaboratore ai dati dell'indice di ricerca

    • Lettore di dati dell'indice di ricerca

Ottenere l'endpoint

Ogni servizio ricerca di intelligenza artificiale di Azure ha un endpoint, ovvero un URL univoco che identifica e fornisce l'accesso alla rete al servizio. In una sezione successiva si specifica questo endpoint per connettersi al servizio di ricerca tramite programmazione.

Per ottenere l'endpoint:

  1. Accedere al portale di Azure e selezionare il servizio di ricerca.

  2. Nel riquadro sinistro selezionare Panoramica.

  3. Prendere nota dell'endpoint, che dovrebbe essere simile a https://my-service.search.windows.net.

Configurare l'ambiente

  1. Usare Git per clonare il repository di esempio.

    git clone https://github.com/Azure-Samples/azure-search-rest-samples
    
  2. Passare alla cartella di avvio rapido e aprirla in Visual Studio Code.

    cd azure-search-rest-samples/Quickstart-vectors
    code .
    
  3. In az-search-quickstart-vectors.restsostituire il valore segnaposto per @baseUrl con l'URL ottenuto in Ottenere l'endpoint.

  4. Per l'autenticazione senza chiave con Microsoft Entra ID, accedere all'account Azure. Se si hanno più sottoscrizioni, selezionare quella che contiene il servizio Ricerca intelligenza artificiale di Azure.

    az login
    
  5. Per l'autenticazione senza chiave con Microsoft Entra ID, generare un token di accesso.

    az account get-access-token --scope https://search.azure.com/.default --query accessToken -o tsv
    
  6. Sostituire il valore segnaposto per @token con il token di accesso del passaggio precedente.

Eseguire il codice

  1. In ### List existing indexes by nameselezionare Invia richiesta per verificare la connessione.

    Una risposta dovrebbe essere visualizzata in un riquadro adiacente. Se sono presenti indici esistenti, vengono elencati. In caso contrario, l'elenco è vuoto. Se il codice HTTP è 200 OK, si è pronti per procedere.

  2. Inviare le richieste rimanenti in sequenza per creare un indice vettoriale, caricare documenti ed eseguire diversi tipi di query vettoriali.

Risultato

Ogni richiesta di query restituisce risultati JSON. L'esempio seguente è l'output della richiesta, che mostra i risultati della ### Run a single vector query ricerca vettoriale classificati in base al punteggio di somiglianza.

{
  "@odata.count": 5,
  "value": [
    {
      "@search.score": 0.6605852,
      "HotelId": "48",
      "HotelName": "Nordick's Valley Motel",
      "Description": "Only 90 miles (about 2 hours) from the nation's capital and nearby most everything the historic valley has to offer. Hiking? Wine Tasting? Exploring the caverns? It's all nearby and we have specially priced packages to help make our B&B your home base for fun while visiting the valley.",
      "Category": "Boutique",
      "Tags": [
        "continental breakfast",
        "air conditioning",
        "free wifi"
      ]
    },
    {
      "@search.score": 0.6333684,
      "HotelId": "13",
      "HotelName": "Luxury Lion Resort",
      "Description": "Unmatched Luxury. Visit our downtown hotel to indulge in luxury accommodations. Moments from the stadium and transportation hubs, we feature the best in convenience and comfort.",
      "Category": "Luxury",
      "Tags": [
        "bar",
        "concierge",
        "restaurant"
      ]
    },
    {
      "@search.score": 0.605672,
      "HotelId": "4",
      "HotelName": "Sublime Palace Hotel",
      "Description": "Sublime Palace Hotel is located in the heart of the historic center of Sublime in an extremely vibrant and lively area within short walking distance to the sites and landmarks of the city and is surrounded by the extraordinary beauty of churches, buildings, shops and monuments. Sublime Cliff is part of a lovingly restored 19th century resort, updated for every modern convenience.",
      "Category": "Boutique",
      "Tags": [
        "concierge",
        "view",
        "air conditioning"
      ]
    },
    {
      "@search.score": 0.6026341,
      "HotelId": "49",
      "HotelName": "Swirling Currents Hotel",
      "Description": "Spacious rooms, glamorous suites and residences, rooftop pool, walking access to shopping, dining, entertainment and the city center. Each room comes equipped with a microwave, a coffee maker and a minifridge. In-room entertainment includes complimentary W-Fi and flat-screen TVs.",
      "Category": "Suite",
      "Tags": [
        "air conditioning",
        "laundry service",
        "24-hour front desk service"
      ]
    },
    {
      "@search.score": 0.57902366,
      "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",
      "Tags": [
        "pool",
        "free wifi",
        "air conditioning",
        "concierge"
      ]
    }
  ]
}

Informazioni sul codice

Annotazioni

I frammenti di codice in questa sezione potrebbero essere stati modificati per la leggibilità. Per un esempio funzionante completo, vedere il codice sorgente.

Dopo aver eseguito il codice, è possibile suddividere i passaggi principali:

  1. Creare un indice vettoriale
  2. Caricare documenti nell'indice
  3. Eseguire una query sull'indice

Creare un indice vettoriale

Prima di aggiungere contenuto a Ricerca di intelligenza artificiale di Azure, è necessario creare un indice per definire la modalità di archiviazione e strutturazione del contenuto. Questo avvio rapido quindi chiama Indexes - Create (API REST) per creare un indice vettoriale, denominato hotels-vector-quickstart, e le relative strutture di dati fisiche nel servizio di ricerca.

Lo schema dell'indice è organizzato in base al contenuto dell'hotel. I dati di esempio sono costituiti da descrizioni vettoriali e non vettoriali di hotel fittizi. Nell'estratto seguente viene illustrata la struttura chiave della ### Create a new index richiesta.

PUT {{baseUrl}}/indexes/hotels-vector-quickstart?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "name": "hotels-vector-quickstart",
    "fields": [
        { "name": "HotelId", "type": "Edm.String", "key": true, "filterable": true },
        { "name": "HotelName", "type": "Edm.String", "searchable": true },
        { "name": "Description", "type": "Edm.String", "searchable": true },
        {
            "name": "DescriptionVector",
            "type": "Collection(Edm.Single)",
            "searchable": true,
            "dimensions": 1536,
            "vectorSearchProfile": "my-vector-profile"
        },
        { "name": "Category", "type": "Edm.String", "filterable": true, "facetable": true },
        { "name": "Tags", "type": "Collection(Edm.String)", "filterable": true, "facetable": true }
        // Additional fields omitted for brevity
    ],
    "vectorSearch": {
        "algorithms": [
            { "name": "hnsw-vector-config", "kind": "hnsw" }
        ],
        "profiles": [
            { "name": "my-vector-profile", "algorithm": "hnsw-vector-config" }
        ]
    },
    "semantic": {
        "configurations": [
            {
                "name": "semantic-config",
                "prioritizedFields": {
                    "titleField": { "fieldName": "HotelName" },
                    "prioritizedContentFields": [{ "fieldName": "Description" }]
                }
            }
        ]
    }
}

Aspetti chiave:

  • Questo particolare indice supporta più funzionalità di ricerca:

  • La dimensions proprietà deve corrispondere alle dimensioni di output del modello di incorporamento. Questo avvio rapido usa 1,536 dimensioni in corrispondenza al modello text-embedding-ada-002.

  • La sezione vectorSearch definisce l'algoritmo ANN (Approximate Nearest Neighbor). Gli algoritmi supportati includono HNSW (Hierarchical Navigable Small World) e KNN (K-Nearest Neighbor). Per altre informazioni, vedere Pertinenza nella ricerca vettoriale.

Caricare documenti nell'indice

Gli indici appena creati sono vuoti. Per popolare un indice e renderlo ricercabile, è necessario caricare documenti JSON conformi allo schema dell'indice.

In Ricerca di intelligenza artificiale di Azure i documenti fungono da input per l'indicizzazione e gli output per le query. Per semplicità, questa guida introduttiva fornisce documenti di esempio relativi agli hotel come JSON in linea. Negli scenari di produzione, tuttavia, il contenuto viene spesso estratto da origini dati connesse e trasformato in JSON usando indicizzatori.

Questo avvio rapido chiama Documents - Index (API REST) per aggiungere documenti su hotel di esempio all'indice. Nell'estratto seguente viene illustrata la struttura della ### Upload 7 documents richiesta.

POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/index?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "value": [
        {
            "@search.action": "mergeOrUpload",
            "HotelId": "1",
            "HotelName": "Stay-Kay City Hotel",
            "Description": "This classic hotel is ideally located on the main commercial artery of the city...",
            "DescriptionVector": [-0.0347, 0.0289, ... ],  // 1536 floats
            "Category": "Boutique",
            "Tags": ["view", "air conditioning", "concierge"],
            "ParkingIncluded": false,
            "Rating": 3.60,
            "Address": { "City": "New York", "StateProvince": "NY" },
            "Location": { "type": "Point", "coordinates": [-73.975403, 40.760586] }
        }
        // Additional documents omitted for brevity
    ]
}

Aspetti chiave:

  • Ogni documento nella value matrice rappresenta un hotel e contiene campi che corrispondono allo schema dell'indice. Il @search.action parametro specifica l'operazione da eseguire per ogni documento. In questo avvio rapido si utilizza mergeOrUpload, che aggiunge il documento se non esiste o lo aggiorna se esiste.

  • I documenti nel payload sono costituiti da campi definiti nello schema dell'indice.

Eseguire una query sull'indice

Le query nel file di esempio illustrano modelli di ricerca diversi. Le query vettoriali di esempio si basano su due stringhe:

  • Stringa di ricerca full-text: "historic hotel walk to restaurants and shopping"

  • Stringa di query vettoriale: "quintessential lodging near running trails, eateries, retail" (vettorializzata in una rappresentazione matematica)

La stringa di query vettoriale è semanticamente simile alla stringa di ricerca full-text, ma include termini che non esistono nell'indice. Una ricerca di sola parola chiave per la stringa di query vettoriale restituisce zero risultati. Tuttavia, la ricerca vettoriale trova corrispondenze pertinenti in base al significato anziché alle parole chiave esatte.

Gli esempi seguenti iniziano con una query vettoriale di base e aggiungono progressivamente filtri, ricerca di parole chiave e reranking semantico.

La ### Run a single vector query richiesta illustra uno scenario di base in cui si desidera trovare descrizioni dei documenti che corrispondono strettamente alla stringa di query vettoriale. La vectorQueries matrice configura la ricerca vettoriale:

  • k limita il numero di risultati restituiti in base alla somiglianza del vettore.
  • fields specifica il campo vettoriale su cui eseguire la ricerca.
POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/search?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "count": true,
    "select": "HotelId, HotelName, Description, Category, Tags",
    "vectorQueries": [
        {
            "vector": [ ... ],  // 1536-dimensional vector of "quintessential lodging near running trails, eateries, retail"
            "k": 5,
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true
        }
    ]
}

Ricerca a vettore singolo con un filtro

In Ricerca di intelligenza artificiale di Azure i filtri si applicano ai campi non vettoriali in un indice. La ### Run a vector query with a filter richiesta filtra sul Tags campo per filtrare tutti gli hotel che non forniscono wi-fi gratuito.

POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/search?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "count": true,
    "select": "HotelId, HotelName, Description, Category, Tags",
    "filter": "Tags/any(tag: tag eq 'free wifi')",
    "vectorFilterMode": "postFilter",
    "vectorQueries": [
        {
            "vector": [ ... ],  // 1536-dimensional vector
            "k": 7,
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true
        }
    ]
}

Ricerca a vettore singolo con un filtro geografico

È possibile specificare un filtro spaziale geografico per limitare i risultati a un'area geografica specifica. La ### Run a vector query with a geo filter richiesta specifica un punto geografico (Washington D.C., utilizzando coordinate di longitudine e latitudine) e restituisce gli hotel entro 300 chilometri. Il vectorFilterMode parametro determina quando viene eseguito il filtro. In questo caso, postFilter esegue il filtro dopo la ricerca vettoriale.

POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/search?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "count": true,
    "select": "HotelId, HotelName, Address/City, Address/StateProvince, Description",
    "filter": "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",
    "vectorFilterMode": "postFilter",
    "top": 5,
    "facets": [ "Address/StateProvince"],
    "vectorQueries": [
        {
            "vector": [ ... ],  // 1536-dimensional vector
            "k": 5,
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true
        }
    ]
}

La ricerca ibrida combina query full-text e vettoriali in una singola richiesta. La ### Run a hybrid query richiesta esegue simultaneamente entrambi i tipi di query e quindi usa La fusione di rango reciproco (RRF) per unire i risultati in una classificazione unificata. RRF usa l'inverso delle classifiche dei risultati di ogni set di risultati per produrre una classifica unificata. Si noti che i punteggi di ricerca ibrida sono uniformemente inferiori ai punteggi di query singola.

POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/search?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "count": true,
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelId, HotelName, Category, Tags, Description",
    "top": 5,
    "vectorQueries": [
        {
            "vector": [ ... ],  // 1536-dimensional vector
            "k": 5,
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true
        }
    ]
}

La ### Run a hybrid query with semantic reranking richiesta illustra la classificazione semantica, che classifica i risultati in base alla comprensione del linguaggio.

POST {{baseUrl}}/indexes/hotels-vector-quickstart/docs/search?api-version={{api-version}}  HTTP/1.1
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "count": true,
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelId, HotelName, Category, Description",
    "queryType": "semantic",
    "semanticConfiguration": "semantic-config",
    "top": 5,
    "vectorQueries": [
        {
            "vector": [ ... ],  // 1536-dimensional vector
            "k": 7,
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true
        }
    ]
}

Confrontare questi risultati con i risultati della ricerca ibrida della query precedente. Senza reranking semantico, Sublime Palace Hotel si classifica primo perché la fusione di rango reciproco (RRF) combina il testo e i punteggi vettoriali per produrre un risultato combinato. Dopo il reranking semantico, Swirling Currents Hotel si sposta al primo posto.

Il ranker semantico usa modelli di comprensione automatica per valutare il livello di corrispondenza di ogni risultato con la finalità della query. La descrizione dell'Hotel Swirling Currents menziona "walking access to shopping, dining, entertainment and the city center", che è strettamente allineata con la ricerca "walk to restaurants and shopping". Questa corrispondenza di rilevanza semantica per ristoranti e negozi nelle vicinanze lo colloca al di sopra del Sublime Palace Hotel, che nella descrizione non mette in evidenza servizi raggiungibili a piedi.

Aspetti chiave:

  • In una ricerca ibrida è possibile integrare la ricerca vettoriale con la ricerca full-text sulle parole chiave. I filtri e la classificazione semantica si applicano solo al contenuto testuale, non ai vettori.

Pulire le risorse

Quando si lavora nella propria sottoscrizione, è consigliabile completare un progetto rimuovendo le risorse non più necessarie. Le risorse lasciate in esecuzione possono avere un costo.

Nel portale di Azure selezionare Tutte le risorse o Gruppidi risorse nel riquadro sinistro per trovare e gestire le risorse. È possibile eliminare le risorse singolarmente o eliminare il gruppo di risorse per rimuovere tutte le risorse contemporaneamente.

In caso contrario, è possibile inviare la richiesta ### Delete an index per eliminazione l'indice creato in questo avvio rapido.