Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Se você estiver usando a versão 1.0.2 prévia ou anterior do SDK do .NET do Azure Search, este artigo ajudará você a atualizar seu aplicativo para usar a versão 1.1.
Para obter um passo a passo mais geral do SDK, incluindo exemplos, consulte Como usar o Azure Search de um aplicativo .NET.
Observação
Depois de atualizar para a versão 1.1 ou se você já estiver usando uma versão entre 1.1 e 2.0-preview inclusive, você deverá atualizar para a versão 3. Consulte a atualização para o SDK do .NET do Azure Search versão 3 para obter instruções.
Primeiro, atualize a referência do NuGet para Microsoft.Azure.Search usando o Console do Gerenciador de Pacotes NuGet ou clicando com o botão direito do mouse nas referências do projeto e selecionando "Gerenciar Pacotes NuGet..." no Visual Studio.
Depois que o NuGet baixar os novos pacotes e suas dependências, recompile seu projeto.
Se você já estava usando a versão 1.0.0-preview, 1.0.1-preview ou 1.0.2-preview, a compilação deve ser bem-sucedida e você está pronto para começar!
Se você já estava usando a versão 0.13.0-preview ou anterior, verá erros de build como o seguinte:
Program.cs(137,56,137,62): error CS0117: 'Microsoft.Azure.Search.Models.IndexBatch' does not contain a definition for 'Create'
Program.cs(137,99,137,105): error CS0117: 'Microsoft.Azure.Search.Models.IndexAction' does not contain a definition for 'Create'
Program.cs(146,41,146,54): error CS1061: 'Microsoft.Azure.Search.IndexBatchException' does not contain a definition for 'IndexResponse' and no extension method 'IndexResponse' accepting a first argument of type 'Microsoft.Azure.Search.IndexBatchException' could be found (are you missing a using directive or an assembly reference?)
Program.cs(163,13,163,42): error CS0246: The type or namespace name 'DocumentSearchResponse' could not be found (are you missing a using directive or an assembly reference?)
A próxima etapa é corrigir os erros de build um a um. A maioria exigirá a alteração de alguns nomes de classe e método que foram renomeado no SDK. A lista de alterações interruptivas na versão 1.1 contém essas alterações de nome.
Se você estiver usando classes personalizadas para modelar seus documentos e essas classes tiverem propriedades de tipos primitivos não anuláveis (por exemplo, int ou bool em C#), haverá uma correção de bug na versão 1.1 do SDK da qual você deve estar ciente. Consulte correções de bug na versão 1.1 para obter mais detalhes.
Por fim, depois de corrigir erros de build, você pode fazer alterações em seu aplicativo para aproveitar a nova funcionalidade, se desejar.
Lista de alterações interruptivas na versão 1.1
A lista a seguir é ordenada pela probabilidade de que a alteração afete o código do aplicativo.
Alterações de IndexBatch e IndexAction
IndexBatch.Create foi renomeado para IndexBatch.New e não tem mais um argumento params. Você pode usar IndexBatch.New para lotes que misturam diferentes tipos de ações (mesclagens, exclusões etc.). Além disso, há novos métodos estáticos para criar lotes em que todas as ações são as mesmas: Delete, , Mergee MergeOrUploadUpload.
IndexAction não tem mais construtores públicos e suas propriedades agora são imutáveis. Você deve usar os novos métodos estáticos para criar ações para diferentes finalidades: Delete, , Mergee MergeOrUploadUpload.
IndexAction.Create foi removido. Se você usou uma sobrecarga que aceita apenas um documento, certifique-se de usar Upload ao invés disso.
Exemplo
Se o código tiver esta aparência:
var batch = IndexBatch.Create(documents.Select(doc => IndexAction.Create(doc)));
indexClient.Documents.Index(batch);
Você pode alterá-lo para corrigir erros de build:
var batch = IndexBatch.New(documents.Select(doc => IndexAction.Upload(doc)));
indexClient.Documents.Index(batch);
Se desejar, você pode simplificar ainda mais isso:
var batch = IndexBatch.Upload(documents);
indexClient.Documents.Index(batch);
Alterações de IndexBatchException
IndexBatchException.IndexResponse propriedade foi renomeada para IndexingResults, e agora seu tipo é IList<IndexingResult>.
Exemplo
Se o código tiver esta aparência:
catch (IndexBatchException e)
{
Console.WriteLine(
"Failed to index some of the documents: {0}",
String.Join(", ", e.IndexResponse.Results.Where(r => !r.Succeeded).Select(r => r.Key)));
}
Você pode alterá-lo para corrigir erros de build:
catch (IndexBatchException e)
{
Console.WriteLine(
"Failed to index some of the documents: {0}",
String.Join(", ", e.IndexingResults.Where(r => !r.Succeeded).Select(r => r.Key)));
}
Alterações no método de operação
Cada operação no SDK do .NET do Azure Search é exposta como um conjunto de sobrecargas de método para chamadores síncronos e assíncronos. As assinaturas e a fatoração dessas sobrecargas de método foram alteradas na versão 1.1.
Por exemplo, a operação "Obter Estatísticas de Índice" em versões mais antigas do SDK expôs estas assinaturas:
Em IIndexOperations:
// Asynchronous operation with all parameters
Task<IndexGetStatisticsResponse> GetStatisticsAsync(
string indexName,
CancellationToken cancellationToken);
Em IndexOperationsExtensions:
// Asynchronous operation with only required parameters
public static Task<IndexGetStatisticsResponse> GetStatisticsAsync(
this IIndexOperations operations,
string indexName);
// Synchronous operation with only required parameters
public static IndexGetStatisticsResponse GetStatistics(
this IIndexOperations operations,
string indexName);
As assinaturas do método para a mesma operação na versão 1.1 são semelhantes a esta:
Em IIndexesOperations:
// Asynchronous operation with lower-level HTTP features exposed
Task<AzureOperationResponse<IndexGetStatisticsResult>> GetStatisticsWithHttpMessagesAsync(
string indexName,
SearchRequestOptions searchRequestOptions = default(SearchRequestOptions),
Dictionary<string, List<string>> customHeaders = null,
CancellationToken cancellationToken = default(CancellationToken));
Em IndexesOperationsExtensions:
// Simplified asynchronous operation
public static Task<IndexGetStatisticsResult> GetStatisticsAsync(
this IIndexesOperations operations,
string indexName,
SearchRequestOptions searchRequestOptions = default(SearchRequestOptions),
CancellationToken cancellationToken = default(CancellationToken));
// Simplified synchronous operation
public static IndexGetStatisticsResult GetStatistics(
this IIndexesOperations operations,
string indexName,
SearchRequestOptions searchRequestOptions = default(SearchRequestOptions));
A partir da versão 1.1, o SDK do .NET do Azure Search organiza os métodos de operação de forma diferente:
- Os parâmetros opcionais agora são modelados como parâmetros padrão em vez de sobrecargas de método adicionais. Isso reduz o número de sobrecargas de método, às vezes dramaticamente.
- Os métodos de extensão agora ocultam muitos dos detalhes desnecessários de HTTP do chamador. Por exemplo, versões mais antigas do SDK devolviam um objeto de resposta com um código de status HTTP, que muitas vezes você não precisava verificar, pois os métodos de operação lançavam
CloudExceptionpara qualquer código de status que indicasse um erro. Os novos métodos de extensão apenas retornam objetos de modelo, poupando o trabalho de ter que desembrulhá-los no seu código. - Por outro lado, as interfaces principais agora expõem métodos que oferecem mais controle no nível HTTP se você precisar dele. Agora você pode passar cabeçalhos HTTP personalizados para serem incluídos nas solicitações; o novo tipo de retorno
AzureOperationResponse<T>fornece acesso direto aoHttpRequestMessageeHttpResponseMessagepara a operação.AzureOperationResponseé definido noMicrosoft.Rest.Azurenamespace e substituiHyak.Common.OperationResponse.
Alterações de Parâmetros de Pontuação
Uma nova classe nomeada ScoringParameter foi adicionada no SDK mais recente para facilitar o provisionamento de parâmetros para perfis de pontuação em uma consulta de pesquisa. Anteriormente, a propriedade ScoringProfiles da classe SearchParameters era do tipo IList<string>; agora é do tipo IList<ScoringParameter>.
Exemplo
Se o código tiver esta aparência:
var sp = new SearchParameters();
sp.ScoringProfile = "jobsScoringFeatured"; // Use a scoring profile
sp.ScoringParameters = new[] { "featuredParam-featured", "mapCenterParam-" + lon + "," + lat };
Você pode alterá-lo para corrigir erros de build:
var sp = new SearchParameters();
sp.ScoringProfile = "jobsScoringFeatured"; // Use a scoring profile
sp.ScoringParameters =
new[]
{
new ScoringParameter("featuredParam", new[] { "featured" }),
new ScoringParameter("mapCenterParam", GeographyPoint.Create(lat, lon))
};
Alterações de classe de modelo
Devido às alterações de assinatura descritas nas alterações de método de operação, muitas classes no Microsoft.Azure.Search.Models namespace foram renomeada ou removidas. Por exemplo:
-
IndexDefinitionResponsefoi substituído porAzureOperationResponse<Index> -
DocumentSearchResponsefoi renomeado paraDocumentSearchResult -
IndexResultfoi renomeado paraIndexingResult -
Documents.Count()agora retorna umlongcom a contagem de documentos em vez de umDocumentCountResponse -
IndexGetStatisticsResponsefoi renomeado paraIndexGetStatisticsResult -
IndexListResponsefoi renomeado paraIndexListResult
Para resumir, OperationResponseas classes derivadas que existiam apenas para encapsular um objeto de modelo foram removidas. As classes restantes tiveram seu sufixo alterado de Response para Result.
Exemplo
Se o código tiver esta aparência:
IndexerGetStatusResponse statusResponse = null;
try
{
statusResponse = _searchClient.Indexers.GetStatus(indexer.Name);
}
catch (Exception ex)
{
Console.WriteLine("Error polling for indexer status: {0}", ex.Message);
return;
}
IndexerExecutionResult lastResult = statusResponse.ExecutionInfo.LastResult;
Você pode alterá-lo para corrigir erros de build:
IndexerExecutionInfo status = null;
try
{
status = _searchClient.Indexers.GetStatus(indexer.Name);
}
catch (Exception ex)
{
Console.WriteLine("Error polling for indexer status: {0}", ex.Message);
return;
}
IndexerExecutionResult lastResult = status.LastResult;
Classes de resposta e IEnumerable
Uma alteração adicional que pode afetar seu código é que as classes de resposta que contêm coleções não são mais implementadas IEnumerable<T>. Em vez disso, você pode acessar a propriedade da coleção diretamente. Por exemplo, se o código tiver esta aparência:
DocumentSearchResponse<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response)
{
Console.WriteLine(result.Document);
}
Você pode alterá-lo para corrigir erros de build:
DocumentSearchResult<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response.Results)
{
Console.WriteLine(result.Document);
}
Caso especial para aplicativos Web
Se você tiver um aplicativo Web que serializa DocumentSearchResponse diretamente para enviar resultados de pesquisa para o navegador, será necessário alterar seu código, ou os resultados não serão serializados corretamente. Por exemplo, se o código tiver esta aparência:
public ActionResult Search(string q = "")
{
// If blank search, assume they want to search everything
if (string.IsNullOrWhiteSpace(q))
q = "*";
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = _featuresSearch.Search(q)
};
}
Você pode alterá-la obtendo a propriedade .Results da resposta de pesquisa para corrigir a renderização dos resultados da pesquisa.
public ActionResult Search(string q = "")
{
// If blank search, assume they want to search everything
if (string.IsNullOrWhiteSpace(q))
q = "*";
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = _featuresSearch.Search(q).Results
};
}
Você terá que procurar esses casos em seu código por conta própria; O compilador não avisará você porque JsonResult.Data é do tipo object.
Alterações de CloudException
A CloudException classe passou do Hyak.Common namespace para o Microsoft.Rest.Azure namespace. Além disso, a propriedade Error foi renomeada para Body.
Alterações de SearchServiceClient e SearchIndexClient
O tipo da Credentials propriedade foi alterado de SearchCredentials para sua classe base. ServiceClientCredentials Se você precisar acessar o SearchCredentials de um SearchIndexClient ou SearchServiceClient, use a propriedade nova SearchCredentials.
Em versões mais antigas do SDK, SearchServiceClient e SearchIndexClient tinham construtores que aceitavam um parâmetro HttpClient. Eles foram substituídos por construtores que recebem um HttpClientHandler e uma matriz de objetos de DelegatingHandler. Isso facilita a instalação de manipuladores personalizados para pré-processar solicitações HTTP, se necessário.
Por fim, os construtores que levavam um Uri e SearchCredentials foram alterados. Por exemplo, se você tiver um código semelhante a este:
var client =
new SearchServiceClient(
new SearchCredentials("abc123"),
new Uri("http://myservice.search.windows.net"));
Você pode alterá-lo para corrigir erros de build:
var client =
new SearchServiceClient(
new Uri("http://myservice.search.windows.net"),
new SearchCredentials("abc123"));
Observe também que o tipo do parâmetro de credenciais foi alterado para ServiceClientCredentials. É improvável que isso afete seu código, uma vez que SearchCredentials é derivado de ServiceClientCredentials.
Passando um ID de solicitação
Em versões mais antigas do SDK, você podia definir uma ID de solicitação no SearchServiceClient ou SearchIndexClient, e ela seria incluída em todas as requisições para a API REST. Isso é útil para solucionar problemas com seu serviço de pesquisa se você precisar entrar em contato com o suporte. No entanto, é mais útil definir uma ID de solicitação exclusiva para cada operação em vez de usar a mesma ID para todas as operações. Por esse motivo, os SetClientRequestId métodos de SearchServiceClient e SearchIndexClient foram removidos. Em vez disso, você pode passar uma ID de solicitação para cada método de operação por meio do parâmetro opcional SearchRequestOptions .
Observação
Em uma versão futura do SDK, adicionaremos um novo mecanismo para definir uma ID de solicitação globalmente nos objetos cliente que seja consistente com a abordagem usada por outros SDKs do Azure.
Exemplo
Se você tiver um código semelhante a este:
client.SetClientRequestId(Guid.NewGuid());
...
long count = client.Documents.Count();
Você pode alterá-lo para corrigir erros de build:
long count = client.Documents.Count(new SearchRequestOptions(requestId: Guid.NewGuid()));
Alterações no nome da interface
Os nomes da interface do grupo de operações foram alterados para serem consistentes com seus nomes de propriedade correspondentes:
- O tipo de
ISearchServiceClient.Indexesfoi renomeado deIIndexOperationsparaIIndexesOperations. - O tipo de
ISearchServiceClient.Indexersfoi renomeado deIIndexerOperationsparaIIndexersOperations. - O tipo de
ISearchServiceClient.DataSourcesfoi renomeado deIDataSourceOperationsparaIDataSourcesOperations. - O tipo de
ISearchIndexClient.Documentsfoi renomeado deIDocumentOperationsparaIDocumentsOperations.
É improvável que essa alteração afete seu código, a menos que você tenha criado simulações dessas interfaces para fins de teste.
Correções de bug na versão 1.1
Houve um bug em versões mais antigas do SDK do .NET do Azure Search relacionadas à serialização de classes de modelo personalizadas. O bug poderá ocorrer se você criou uma classe de modelo personalizada com uma propriedade de um tipo de valor não anulável.
Etapas para reproduzir
Crie uma classe de modelo personalizada com uma propriedade de tipo de valor não anulável. Por exemplo, adicione uma propriedade pública UnitCount do tipo int em vez de int?.
Se você indexar um documento com o valor padrão desse tipo (por exemplo, 0 para int), o campo será nulo no Azure Search. Se você procurar posteriormente por esse documento, a Search chamada lançará uma exceção JsonSerializationException reclamando que não pode converter null para int.
Além disso, os filtros podem não funcionar conforme o esperado, pois nulo foi gravado no índice em vez do valor pretendido.
Corrigir detalhes
Corrigimos esse problema na versão 1.1 do SDK. Agora, se você tiver uma classe de modelo como esta:
public class Model
{
public string Key { get; set; }
public int IntValue { get; set; }
}
e você definir IntValue como 0, esse valor agora é serializado corretamente como 0 no fio e armazenado como 0 no índice. O tropeço redondo também funciona conforme o esperado.
Há um problema potencial a ser conhecido com essa abordagem: se você usar um tipo de modelo com uma propriedade não anulável, precisará garantir que nenhum documento em seu índice contenha um valor nulo para o campo correspondente. Nem o SDK nem a API REST do Azure Search ajudarão você a impor isso.
Isso não é apenas uma preocupação hipotética: imagine um cenário em que você adiciona um novo campo a um índice existente do tipo Edm.Int32. Depois de atualizar a definição de índice, todos os documentos terão um valor nulo para esse novo campo (já que todos os tipos são anuláveis no Azure Search). Se, em seguida, você usar uma classe de modelo com uma propriedade não anulável int para esse campo, obterá uma JsonSerializationException destas ao tentar recuperar documentos:
Error converting value {null} to type 'System.Int32'. Path 'IntValue'.
Por esse motivo, ainda recomendamos que você use tipos anuláveis em suas classes de modelo como uma prática recomendada.
Para obter mais detalhes sobre esse bug e a correção, consulte esse problema no GitHub.