Compartilhar via


Pesquisar Dados com a Pesquisa do Azure e Xamarin.Forms

A Pesquisa do Azure é 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 de Pesquisa do Microsoft Azure para integrar a Pesquisa do Azure em um Xamarin.Forms aplicativo.

Visão geral

Os dados são armazenados na Pesquisa do Azure como índices e documentos. Um índice é um armazenamento de dados que pode ser pesquisado pelo serviço de Pesquisa do Azure 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 a Pesquisa do Azure, as solicitações são feitas para um índice específico no serviço de pesquisa.

Cada solicitação feita à Pesquisa do Azure deve incluir o nome do serviço e uma chave de API. Há dois tipos de chave de API:

  • As chaves de administração concedem direitos totais a todas as operações. Isso inclui o gerenciamento do serviço, a criação e a exclusão de í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 a Pesquisa do Azure é 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 em conjunto. Quando usada em conjunto, a consulta de filtro é aplicada primeiro a todo o índice e, em seguida, a consulta de pesquisa é executada nos resultados da consulta de filtro.

A Pesquisa do Azure 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 a Pesquisa do Azure em um Xamarin.Forms aplicativo é o seguinte:

  1. Crie um serviço de Pesquisa do Azure. Para obter mais informações, consulte Criar um serviço de Pesquisa do Azure usando o Portal do Azure.
  2. Remova o Silverlight como uma estrutura de destino da Xamarin.Forms solução Portable Class Library (PCL). Isso pode ser feito alterando o perfil PCL para qualquer perfil que ofereça suporte ao desenvolvimento entre plataformas, mas não ofereça 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

Deve ser definido um esquema de índice que mapeie para 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 a Pesquisa do Azure 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 de Pesquisa do Azure. A chave admin é 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 a Pesquisa do Azure.

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 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 em 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

A alteração de um índice depois que ele é implantado envolve a reconstrução e o recarregamento dos dados.

Um Index objeto pode, opcionalmente, 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 de Pesquisa do Azure usando o SDK do .NET.

Excluindo o índice de pesquisa do Azure

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

searchClient.Indexes.Delete(Constants.Index);

Carregando dados no índice de pesquisa do Azure

Depois de definir o índice, os dados podem ser carregados 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 hospedado em uma Máquina Virtual do Azure.
  • Modelo de envio por push – os dados são enviados programaticamente para o índice. Esse é 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 à Pesquisa do Azure 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 for novo, ou substituído, se já existir. O IndexBatch objeto é então enviado para o índice chamando o Documents.IndexSearchIndexClient método no 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 caso Monkey Pascal para nomes de campo de índice de pesquisa de caso camel. Como alternativa, esse mapeamento também pode ser realizado adicionando o [SerializePropertyNamesAsCamelCase] atributo à Monkey classe.

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

Consultando o índice de pesquisa do Azure

Uma SearchIndexClient instância deve ser criada para consultar um índice. Quando um aplicativo executa consultas, é aconselhável seguir o princípio de privilégio mínimo e criar um SearchIndexClient diretamente, passando a chave de consulta como um 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 de Pesquisa do Azure.

Pesquisar Consultas

O índice pode ser consultado chamando o Documents.SearchAsyncSearchIndexClient método na 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 FilterSearchParameters propriedade do argumento. O exemplo de código a seguir demonstra ambos os 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 ao MonkeysObservableCollection para exibição. As capturas de tela a seguir mostram os resultados da consulta de pesquisa retornados da Pesquisa do Azure:

Resultados da Pesquisa

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

Sugestões de Consultas

A Pesquisa do Azure permite que sugestões sejam solicitadas com base em uma consulta de pesquisa, chamando o Documents.SuggestAsyncSearchIndexClient 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 sugeridor a ser usado (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, a Pesquisa do Azure encontrará sugestões mesmo se houver um caractere substituído ou ausente no texto de pesquisa.
  • HighlightPreTag – a tag que é precedida de acertos de sugestão.
  • HighlightPostTag – a tag que é anexada aos acertos 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 um sucesso. O padrão é 80.
  • Top – o número de sugestões a recuperar. Ele deve ser um 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 ao MonkeysObservableCollection para exibição. As capturas de tela a seguir mostram os resultados de sugestão retornados da Pesquisa do Azure:

Resultados da Sugestão

Observe que, no aplicativo de exemplo, o SuggestAsync método só é chamado 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 em cada pressionamento de tecla.

Resumo

Este artigo demonstrou como usar a Biblioteca de Pesquisa do Microsoft Azure para integrar a Pesquisa do Azure em um Xamarin.Forms aplicativo. A Pesquisa do Azure é 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.