Eseguire ricerche nei dati con Ricerca di Azure e Xamarin.Forms

Download Sample Scaricare l'esempio

Ricerca di Azure è un servizio cloud che offre funzionalità di indicizzazione e query per i dati caricati. In questo modo vengono rimossi i requisiti dell'infrastruttura e le complessità degli algoritmi di ricerca tradizionalmente associati all'implementazione delle funzionalità di ricerca in un'applicazione. Questo articolo illustra come usare la libreria di Ricerca di Microsoft Azure per integrare Ricerca di Azure in un'applicazione Xamarin.Forms .

Panoramica

I dati vengono archiviati in Ricerca di Azure come indici e documenti. Un indice è un archivio di dati che possono essere ricercati dall'servizio di ricerca di Azure ed è concettualmente simile a una tabella di database. Un documento è una singola unità di dati ricercabile in un indice ed è concettualmente simile a una riga di database. Quando si caricano documenti e si inviano query di ricerca a Ricerca di Azure, le richieste vengono inviate a un indice specifico nel servizio di ricerca.

Ogni richiesta inviata a Ricerca di Azure deve includere il nome del servizio e una chiave API. Esistono due tipi di chiave API:

  • Amministrazione chiavi concedono diritti completi a tutte le operazioni. Ciò include la gestione del servizio, la creazione e l'eliminazione di indici e origini dati.
  • Le chiavi di query concedono l'accesso in sola lettura agli indici e ai documenti e devono essere usate dalle applicazioni che eseguono richieste di ricerca.

La richiesta più comune a Ricerca di Azure consiste nell'eseguire una query. È possibile inviare due tipi di query:

Le query di ricerca e le query di filtro possono essere usate separatamente o insieme. Se usata insieme, la query di filtro viene applicata prima all'intero indice e quindi la query di ricerca viene eseguita sui risultati della query di filtro.

Ricerca di Azure supporta anche il recupero di suggerimenti in base all'input di ricerca. Per altre informazioni, vedere Query di suggerimento.

Nota

Se non si ha una sottoscrizione di Azure, creare un account gratuito prima di iniziare.

Attrezzaggio

Il processo di integrazione di Ricerca di Azure in un'applicazione Xamarin.Forms è il seguente:

  1. Creare un servizio di ricerca di Azure. Per altre informazioni, vedere Creare un servizio di ricerca di Azure usando il portale di Azure.
  2. Rimuovere Silverlight come framework di destinazione dalla Xamarin.Forms soluzione Libreria di classi portabile (PCL). A tale scopo, è possibile modificare il profilo PCL in qualsiasi profilo che supporta lo sviluppo multipiattaforma, ma non supporta Silverlight, ad esempio il profilo 151 o il profilo 92.
  3. Aggiungere il pacchetto NuGet della libreria di Ricerca di Microsoft Azure al progetto PCL nella Xamarin.Forms soluzione.

Dopo aver eseguito questi passaggi, l'API della libreria di Microsoft Search può essere usata per gestire gli indici di ricerca e le origini dati, caricare e gestire documenti ed eseguire query.

Creazione di un indice di Ricerca di Azure

È necessario definire uno schema di indice che esegue il mapping alla struttura dei dati da cercare. Questa operazione può essere eseguita nel portale di Azure o a livello di codice usando la SearchServiceClient classe . Questa classe gestisce le connessioni a Ricerca di Azure e può essere usata per creare un indice. Nell'esempio di codice seguente viene illustrato come creare un'istanza di questa classe:

var searchClient =
  new SearchServiceClient(Constants.SearchServiceName, new SearchCredentials(Constants.AdminApiKey));

L'overload del SearchServiceClient costruttore accetta un nome del servizio di ricerca e un SearchCredentials oggetto come argomenti, con l'oggetto che esegue il SearchCredentials wrapping della chiave di amministrazione per l'servizio di ricerca di Azure. La chiave di amministrazione è necessaria per creare un indice.

Nota

Una singola SearchServiceClient istanza deve essere usata in un'applicazione per evitare di aprire troppe connessioni a Ricerca di Azure.

Un indice viene definito dall'oggetto Index , come illustrato nell'esempio di codice seguente:

static void CreateSearchIndex()
{
  var index = new Index()
  {
    Name = Constants.Index,
    Fields = new[]
    {
      new Field("id", DataType.String) { IsKey = true, IsRetrievable = true },
      new Field("name", DataType.String) { IsRetrievable = true, IsFilterable = true, IsSortable = true, IsSearchable = true },
      new Field("location", DataType.String) { IsRetrievable = true, IsFilterable = true, IsSortable = true, IsSearchable = true },
      new Field("details", DataType.String) { IsRetrievable = true, IsFilterable = true, IsSearchable = true },
      new Field("imageUrl", DataType.String) { IsRetrievable = true }
    },
    Suggesters = new[]
    {
      new Suggester("nameSuggester", SuggesterSearchMode.AnalyzingInfixMatching, new[] { "name" })
    }
  };

  searchClient.Indexes.Create(index);
}

La Index.Name proprietà deve essere impostata sul nome dell'indice e la Index.Fields proprietà deve essere impostata su una matrice di Field oggetti. Ogni Field istanza specifica un nome, un tipo e qualsiasi proprietà, che specificano la modalità di utilizzo del campo. Queste proprietà includono:

  • IsKey : indica se il campo è la chiave dell'indice. Un solo campo nell'indice, di tipo DataType.String, deve essere designato come campo chiave.
  • IsFacetable : indica se è possibile eseguire lo spostamento in base a facet in questo campo. Il valore predefinito è false.
  • IsFilterable : indica se il campo può essere usato nelle query di filtro. Il valore predefinito è false.
  • IsRetrievable : indica se il campo può essere recuperato nei risultati della ricerca. Il valore predefinito è true.
  • IsSearchable : indica se il campo è incluso nelle ricerche full-text. Il valore predefinito è false.
  • IsSortable : indica se il campo può essere usato nelle OrderBy espressioni. Il valore predefinito è false.

Nota

La modifica di un indice dopo la distribuzione comporta la ricompilazione e il ricaricamento dei dati.

Un Index oggetto può facoltativamente specificare una Suggesters proprietà che definisce i campi nell'indice da usare per supportare query di suggerimento di ricerca o completamento automatico. La Suggesters proprietà deve essere impostata su una matrice di Suggester oggetti che definiscono i campi utilizzati per compilare i risultati dei suggerimenti di ricerca.

Dopo aver creato l'oggetto, l'indice Index viene creato chiamando Indexes.Create sull'istanza SearchServiceClient di .

Nota

Quando si crea un indice da un'applicazione che deve essere mantenuta reattiva, usare il Indexes.CreateAsync metodo .

Per altre informazioni, vedere Creare un indice di Ricerca di Azure con .NET SDK.

Eliminazione dell'indice di Ricerca di Azure

È possibile eliminare un indice chiamando Indexes.Delete sull'istanza SearchServiceClient di :

searchClient.Indexes.Delete(Constants.Index);

Caricamento di dati nell'indice di Ricerca di Azure

Dopo aver definito l'indice, è possibile caricare i dati usando uno dei due modelli seguenti:

  • Modello pull: i dati vengono inseriti periodicamente da Azure Cosmos DB, database SQL di Azure, Archiviazione BLOB di Azure o SQL Server ospitati in una macchina virtuale di Azure.
  • Modello push: i dati vengono inviati a livello di codice all'indice. Questo è il modello adottato in questo articolo.

È necessario creare un'istanza SearchIndexClient di per importare dati nell'indice. Questa operazione può essere eseguita chiamando il SearchServiceClient.Indexes.GetClient metodo , come illustrato nell'esempio di codice seguente:

static void UploadDataToSearchIndex()
{
  var indexClient = searchClient.Indexes.GetClient(Constants.Index);

  var monkeyList = MonkeyData.Monkeys.Select(m => new
  {
    id = Guid.NewGuid().ToString(),
    name = m.Name,
    location = m.Location,
    details = m.Details,
    imageUrl = m.ImageUrl
  });

  var batch = IndexBatch.New(monkeyList.Select(IndexAction.Upload));
  try
  {
    indexClient.Documents.Index(batch);
  }
  catch (IndexBatchException ex)
  {
    // Sometimes when the Search service is under load, indexing will fail for some
    // documents in the batch. Compensating actions like delaying and retrying should be taken.
    // Here, the failed document keys are logged.
    Console.WriteLine("Failed to index some documents: {0}",
      string.Join(", ", ex.IndexingResults.Where(r => !r.Succeeded).Select(r => r.Key)));
  }
}

I dati da importare nell'indice vengono inseriti in un pacchetto come IndexBatch oggetto , che incapsula una raccolta di IndexAction oggetti . Ogni IndexAction istanza contiene un documento e una proprietà che indica a Ricerca di Azure quale azione eseguire nel documento. Nell'esempio di codice precedente viene specificata l'azione IndexAction.Upload , che comporta l'inserimento del documento nell'indice se è nuovo o sostituito se esiste già. L'oggetto IndexBatch viene quindi inviato all'indice chiamando il Documents.Index metodo sull'oggetto SearchIndexClient . Per informazioni su altre azioni di indicizzazione, vedere Decidere quale azione di indicizzazione usare.

Nota

Solo 1000 documenti possono essere inclusi in una singola richiesta di indicizzazione.

Si noti che nell'esempio di codice precedente la monkeyList raccolta viene creata come oggetto anonimo da una raccolta di Monkey oggetti . In questo modo vengono creati dati per il id campo e viene risolto il mapping dei nomi delle proprietà case Monkey Pascal ai nomi dei campi dell'indice di ricerca tra maiuscole e minuscole camel. In alternativa, questo mapping può essere eseguito anche aggiungendo l'attributo [SerializePropertyNamesAsCamelCase] alla Monkey classe .

Per altre informazioni, vedere Caricare dati in Ricerca di Azure con .NET SDK.

Esecuzione di query sull'indice di Ricerca di Azure

È necessario creare un'istanza SearchIndexClient di per eseguire query su un indice. Quando un'applicazione esegue query, è consigliabile seguire il principio dei privilegi minimi e creare direttamente una SearchIndexClient chiave di query, passando la chiave di query come argomento. In questo modo gli utenti hanno accesso in sola lettura agli indici e ai documenti. Questo approccio è illustrato nell'esempio di codice seguente:

SearchIndexClient indexClient =
  new SearchIndexClient(Constants.SearchServiceName, Constants.Index, new SearchCredentials(Constants.QueryApiKey));

L'overload SearchIndexClient del costruttore accetta un nome del servizio di ricerca, un nome di indice e un SearchCredentials oggetto come argomenti, con l'oggetto che esegue il wrapping della chiave di query per l'servizio di ricerca SearchCredentials di Azure.

Query di ricerca

L'indice può essere sottoposto a query chiamando il Documents.SearchAsync metodo nell'istanza SearchIndexClient di , come illustrato nell'esempio di codice seguente:

async Task AzureSearch(string text)
{
  Monkeys.Clear();

  var searchResults = await indexClient.Documents.SearchAsync<Monkey>(text);
  foreach (SearchResult<Monkey> result in searchResults.Results)
  {
    Monkeys.Add(new Monkey
    {
      Name = result.Document.Name,
      Location = result.Document.Location,
      Details = result.Document.Details,
      ImageUrl = result.Document.ImageUrl
    });
  }
}

Il SearchAsync metodo accetta un argomento di testo di ricerca e un oggetto facoltativo SearchParameters che può essere usato per perfezionare ulteriormente la query. Una query di ricerca viene specificata come argomento di testo di ricerca, mentre è possibile specificare una query di filtro impostando la Filter proprietà dell'argomento SearchParameters . L'esempio di codice seguente illustra entrambi i tipi di query:

var parameters = new SearchParameters
{
  Filter = "location ne 'China' and location ne 'Vietnam'"
};
var searchResults = await indexClient.Documents.SearchAsync<Monkey>(text, parameters);

Questa query di filtro viene applicata all'intero indice e rimuove i documenti dai risultati in cui il location campo non è uguale alla Cina e non uguale al Vietnam. Dopo il filtro, la query di ricerca viene eseguita sui risultati della query di filtro.

Nota

Per filtrare senza eseguire ricerche, passare * come argomento di testo di ricerca.

Il SearchAsync metodo restituisce un DocumentSearchResult oggetto contenente i risultati della query. Questo oggetto viene enumerato, con ogni Document oggetto creato come Monkey oggetto e aggiunto a per la MonkeysObservableCollection visualizzazione. Gli screenshot seguenti mostrano i risultati della query di ricerca restituiti da Ricerca di Azure:

Search Results

Per altre informazioni sulla ricerca e il filtro, vedere Eseguire query sull'indice di Ricerca di Azure usando .NET SDK.

Query di suggerimento

Ricerca di Azure consente di richiedere suggerimenti in base a una query di ricerca chiamando il Documents.SuggestAsync metodo nell'istanza SearchIndexClient di . Questo esempio di codice è illustrato nell'esempio di codice seguente:

async Task AzureSuggestions(string text)
{
  Suggestions.Clear();

  var parameters = new SuggestParameters()
  {
    UseFuzzyMatching = true,
    HighlightPreTag = "[",
    HighlightPostTag = "]",
    MinimumCoverage = 100,
    Top = 10
  };

  var suggestionResults =
    await indexClient.Documents.SuggestAsync<Monkey>(text, "nameSuggester", parameters);

  foreach (var result in suggestionResults.Results)
  {
    Suggestions.Add(new Monkey
    {
      Name = result.Text,
      Location = result.Document.Location,
      Details = result.Document.Details,
      ImageUrl = result.Document.ImageUrl
    });
  }
}

Il SuggestAsync metodo accetta un argomento di testo di ricerca, il nome del suggerimento da usare (definito nell'indice) e un oggetto facoltativo SuggestParameters che può essere usato per perfezionare ulteriormente la query. L'istanza SuggestParameters imposta le proprietà seguenti:

  • UseFuzzyMatching : se impostato su true, Ricerca di Azure troverà suggerimenti anche se nel testo di ricerca è presente un carattere sostituito o mancante.
  • HighlightPreTag : il tag anteporto ai riscontri dei suggerimenti.
  • HighlightPostTag : tag aggiunto ai riscontri dei suggerimenti.
  • MinimumCoverage : rappresenta la percentuale dell'indice che deve essere coperta da una query di suggerimento per segnalare l'esito positivo della query. Il valore predefinito è 80.
  • Top : numero di suggerimenti da recuperare. Deve essere un numero intero compreso tra 1 e 100, con un valore predefinito pari a 5.

L'effetto complessivo è che i primi 10 risultati dell'indice verranno restituiti con l'evidenziazione dei risultati e i risultati includono documenti che includono termini di ricerca digitati in modo analogo.

Il SuggestAsync metodo restituisce un DocumentSuggestResult oggetto contenente i risultati della query. Questo oggetto viene enumerato, con ogni Document oggetto creato come Monkey oggetto e aggiunto a per la MonkeysObservableCollection visualizzazione. Gli screenshot seguenti mostrano i risultati dei suggerimenti restituiti da Ricerca di Azure:

Suggestion Results

Si noti che nell'applicazione di esempio il SuggestAsync metodo viene richiamato solo quando l'utente termina l'input di un termine di ricerca. Tuttavia, può essere usato anche per supportare le query di ricerca completa automaticamente eseguendo su ogni tastopressione.

Riepilogo

Questo articolo ha illustrato come usare la libreria di Ricerca di Microsoft Azure per integrare Ricerca di Azure in un'applicazione Xamarin.Forms . Ricerca di Azure è un servizio cloud che offre funzionalità di indicizzazione e query per i dati caricati. In questo modo vengono rimossi i requisiti dell'infrastruttura e le complessità degli algoritmi di ricerca tradizionalmente associati all'implementazione delle funzionalità di ricerca in un'applicazione.