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:
- Uma consulta de pesquisa pesquisa um ou mais itens em todos os campos pesquisáveis em um índice. As consultas de pesquisa são criadas usando a sintaxe simplificada ou a sintaxe de consulta Lucene. Para obter mais informações, consulte Sintaxe de consulta simples no Azure Search e Sintaxe de consulta Lucene no Azure Search.
- Uma consulta de filtro avalia uma expressão booleana em todos os campos filtráveis em um índice. As consultas de filtro são criadas usando um subconjunto da linguagem de filtro OData. Para obter mais informações, consulte Sintaxe de expressão OData para Azure Search.
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:
- 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.
- 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.
- 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 tipoDataType.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 emOrderBy
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:
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 comotrue
, 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:
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.