Partilhar via


Pesquisar dados com o Azure Search e Xamarin.Forms

O Azure Search é um serviço de nuvem que fornece recursos de indexação e consulta para dados carregados. Isso remove os requisitos de infraestrutura e as complexidades do algoritmo de pesquisa tradicionalmente associados à implementação da funcionalidade de pesquisa em um aplicativo. Este artigo demonstra como usar a Biblioteca do Microsoft Azure Search para integrar o Azure Search a um Xamarin.Forms aplicativo.

Visão geral

Os dados são armazenados no Azure Search como índices e documentos. Um índice é um repositório de dados que pode ser pesquisado pelo serviço Azure Search e é conceitualmente semelhante a uma tabela de banco de dados. Um documento é uma única unidade de dados pesquisáveis em um índice e é conceitualmente semelhante a uma linha de banco de dados. Ao carregar documentos e enviar consultas de pesquisa para o Azure Search, as solicitações são feitas para um índice específico no serviço de pesquisa.

Cada solicitação feita ao Azure Search deve incluir o nome do serviço e uma chave de API. Existem dois tipos de chave de API:

  • As chaves de administrador concedem direitos totais a todas as operações. Isso inclui gerenciar o serviço, criar e excluir índices e fontes de dados.
  • As chaves de consulta concedem acesso somente leitura a índices e documentos e devem ser usadas por aplicativos que emitem solicitações de pesquisa.

A solicitação mais comum para o Azure Search é executar uma consulta. Há dois tipos de consulta que podem ser enviados:

As consultas de pesquisa e as consultas de filtro podem ser usadas separadamente ou juntas. Quando usadas juntas, a consulta de filtro é aplicada primeiro a todo o índice e, em seguida, a consulta de pesquisa é executada nos resultados da consulta de filtro.

O Azure Search também dá suporte à recuperação de sugestões com base na entrada de pesquisa. Para obter mais informações, consulte Consultas de sugestão.

Observação

Se você não tiver uma assinatura do Azure, crie uma conta gratuita antes de começar.

Instalação

O processo para integrar o Azure Search em um Xamarin.Forms aplicativo é o seguinte:

  1. Crie um serviço do Azure Search. Para obter mais informações, consulte Criar um serviço do Azure Search usando o Portal do Azure.
  2. Remova o Silverlight como uma estrutura de destino da Xamarin.Forms solução PCL (Biblioteca de Classes Portátil). Isso pode ser feito alterando o perfil PCL para qualquer perfil que dê suporte ao desenvolvimento multiplataforma, mas não dê suporte ao Silverlight, como o perfil 151 ou o perfil 92.
  3. Adicione o pacote NuGet da Biblioteca de Pesquisa do Microsoft Azure ao projeto PCL na Xamarin.Forms solução.

Depois de executar essas etapas, a API da Biblioteca de Pesquisa da Microsoft pode ser usada para gerenciar índices de pesquisa e fontes de dados, carregar e gerenciar documentos e executar consultas.

Criando um índice do Azure Search

Um esquema de índice deve ser definido para mapear a estrutura dos dados a serem pesquisados. Isso pode ser feito no Portal do Azure ou programaticamente usando a SearchServiceClient classe. Essa classe gerencia conexões com o Azure Search e pode ser usada para criar um índice. O exemplo de código a seguir demonstra como criar uma instância dessa classe:

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

A SearchServiceClient sobrecarga do construtor usa um nome de serviço de pesquisa e um SearchCredentials objeto como argumentos, com o SearchCredentials objeto encapsulando a chave de administrador para o serviço Azure Search. A chave de administração é necessária para criar um índice.

Observação

Uma única SearchServiceClient instância deve ser usada em um aplicativo para evitar a abertura de muitas conexões com o Azure Search.

Um índice é definido pelo Index objeto, conforme demonstrado no exemplo de código a seguir:

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);
}

A Index.Name propriedade deve ser definida como o nome do índice e a Index.Fields propriedade deve ser definida como uma matriz de Field objetos. Cada Field instância especifica um nome, um tipo e quaisquer propriedades, que especificam como o campo é usado. Essas propriedades incluem:

  • IsKey – indica se o campo é a chave do índice. Apenas um campo no índice, do tipo DataType.String, deve ser designado como o campo-chave.
  • IsFacetable – indica se é possível realizar a navegação facetada neste campo. O valor padrão é false.
  • IsFilterable – indica se o campo pode ser usado em consultas de filtro. O valor padrão é false.
  • IsRetrievable – indica se o campo pode ser recuperado nos resultados da pesquisa. O valor padrão é true.
  • IsSearchable – indica se o campo está incluído nas pesquisas de texto completo. O valor padrão é false.
  • IsSortable – indica se o campo pode ser usado em OrderBy expressões. O valor padrão é false.

Observação

Alterar um índice depois que ele é implantado envolve a recriação e o recarregamento dos dados.

Opcionalmente, um Index objeto pode especificar uma Suggesters propriedade, que define os campos no índice a serem usados para dar suporte a consultas de preenchimento automático ou sugestão de pesquisa. A Suggesters propriedade deve ser definida como uma matriz de objetos que definem os campos usados para criar os resultados da sugestão de Suggester pesquisa.

Depois de criar o Index objeto, o índice é criado chamando Indexes.Create a SearchServiceClient instância.

Observação

Ao criar um índice de um aplicativo que deve ser mantido responsivo, use o Indexes.CreateAsync método.

Para obter mais informações, consulte Criar um índice do Azure Search usando o SDK do .NET.

Excluindo o índice do Azure Search

Um índice pode ser excluído chamando Indexes.Delete a SearchServiceClient instância:

searchClient.Indexes.Delete(Constants.Index);

Carregando dados no índice do Azure Search

Depois de definir o índice, os dados podem ser carregados nele usando um dos dois modelos:

  • Modelo de pull – os dados são ingeridos periodicamente do Azure Cosmos DB, do Banco de Dados SQL do Azure, do Armazenamento de Blobs do Azure ou do SQL Server hospedados em uma Máquina Virtual do Azure.
  • Modelo de push – os dados são enviados programaticamente para o índice. Este é o modelo adotado neste artigo.

Uma SearchIndexClient instância deve ser criada para importar dados para o índice. Isso pode ser feito chamando o SearchServiceClient.Indexes.GetClient método, conforme demonstrado no exemplo de código a seguir:

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)));
  }
}

Os dados a serem importados para o índice são empacotados como um IndexBatch objeto, que encapsula uma coleção de IndexAction objetos. Cada IndexAction instância contém um documento e uma propriedade que informa ao Azure Search qual ação executar no documento. No exemplo de código acima, a ação é especificada, o IndexAction.Upload que resulta na inserção do documento no índice se ele for novo ou substituído se ele já existir. Em seguida, o IndexBatch objeto é enviado para o índice chamando o Documents.Index método no SearchIndexClient objeto. Para obter informações sobre outras ações de indexação, consulte Decidir qual ação de indexação usar.

Observação

Apenas 1000 documentos podem ser incluídos em uma única solicitação de indexação.

Observe que, no exemplo de código acima, a monkeyList coleção é criada como um objeto anônimo de uma coleção de Monkey objetos. Isso cria dados para o id campo e resolve o mapeamento de nomes de propriedade de maiúsculas Monkey e minúsculas Pascal para nomes de campos de índice de pesquisa de maiúsculas e minúsculas em maiúsculas e minúsculas. Como alternativa, esse mapeamento também pode ser realizado adicionando o [SerializePropertyNamesAsCamelCase] atributo à Monkey classe.

Para obter mais informações, consulte Carregar dados no Azure Search usando o SDK do .NET.

Consultando o índice do Azure Search

Uma SearchIndexClient instância deve ser criada para consultar um índice. Quando uma aplicação executa consultas, é aconselhável seguir o princípio do privilégio mínimo e criar um SearchIndexClient diretamente, passando a chave de consulta como argumento. Isso garante que os usuários tenham acesso somente leitura a índices e documentos. Essa abordagem é demonstrada no exemplo de código a seguir:

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

A SearchIndexClient sobrecarga do construtor usa um nome de serviço de pesquisa, um nome de índice e um SearchCredentials objeto como argumentos, com o SearchCredentials objeto encapsulando a chave de consulta para o serviço Azure Search.

Pesquisar Consultas

O índice pode ser consultado chamando o Documents.SearchAsync método na SearchIndexClient instância, conforme demonstrado no exemplo de código a seguir:

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
    });
  }
}

O SearchAsync método usa um argumento de texto de pesquisa e um objeto opcional SearchParameters que pode ser usado para refinar ainda mais a consulta. Uma consulta de pesquisa é especificada como o argumento de texto de pesquisa, enquanto uma consulta de filtro pode ser especificada definindo a Filter propriedade do SearchParameters argumento. O exemplo de código a seguir demonstra os dois tipos de consulta:

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

Essa consulta de filtro é aplicada a todo o índice e remove documentos dos resultados em que o location campo não é igual à China e não é igual ao Vietnã. Após a filtragem, a consulta de pesquisa é executada nos resultados da consulta de filtro.

Observação

Para filtrar sem pesquisar, passe * como o argumento de texto de pesquisa.

O SearchAsync método retorna um DocumentSearchResult objeto que contém os resultados da consulta. Esse objeto é enumerado, com cada Document objeto sendo criado como um Monkey objeto e adicionado à exibição.Monkeys ObservableCollection As capturas de tela a seguir mostram os resultados da consulta de pesquisa retornados do Azure Search:

Resultados da Pesquisa

Para obter mais informações sobre pesquisa e filtragem, consulte Consultar o índice do Azure Search usando o SDK do .NET.

Consultas de sugestão

O Azure Search permite que sugestões sejam solicitadas com base em uma consulta de pesquisa, chamando o Documents.SuggestAsync SearchIndexClient método na instância. Isso é demonstrado no exemplo de código a seguir:

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
    });
  }
}

O SuggestAsync método usa um argumento de texto de pesquisa, o nome do sugestor a ser usado (que é definido no índice) e um objeto opcional SuggestParameters que pode ser usado para refinar ainda mais a consulta. A SuggestParameters instância define as seguintes propriedades:

  • UseFuzzyMatching – quando definido como true, o Azure Search encontrará sugestões mesmo que haja um caractere substituído ou ausente no texto da pesquisa.
  • HighlightPreTag – a tag que é anexada aos hits de sugestão.
  • HighlightPostTag – a tag anexada aos hits de sugestão.
  • MinimumCoverage – representa a porcentagem do índice que deve ser coberta por uma consulta de sugestão para que a consulta seja relatada como bem-sucedida. O padrão é 80.
  • Top – o número de sugestões a serem recuperadas. Deve ser um número inteiro entre 1 e 100, com um valor padrão de 5.

O efeito geral é que os 10 principais resultados do índice serão retornados com realce de ocorrência, e os resultados incluirão documentos que incluem termos de pesquisa com grafia semelhante.

O SuggestAsync método retorna um DocumentSuggestResult objeto que contém os resultados da consulta. Esse objeto é enumerado, com cada Document objeto sendo criado como um Monkey objeto e adicionado à exibição.Monkeys ObservableCollection As capturas de tela a seguir mostram os resultados da sugestão retornados do Azure Search:

Resultados da sugestão

Observe que, no aplicativo de exemplo, o SuggestAsync método só é invocado quando o usuário termina de inserir um termo de pesquisa. No entanto, ele também pode ser usado para oferecer suporte a consultas de pesquisa de preenchimento automático, executando cada pressionamento de tecla.

Resumo

Este artigo demonstrou como usar a Biblioteca do Microsoft Azure Search para integrar o Azure Search a um Xamarin.Forms aplicativo. O Azure Search é um serviço de nuvem que fornece recursos de indexação e consulta para dados carregados. Isso remove os requisitos de infraestrutura e as complexidades do algoritmo de pesquisa tradicionalmente associados à implementação da funcionalidade de pesquisa em um aplicativo.