为什么 azure search 抛出 IndexBatchException 而 IndexingResults 没有失败
Why does azure search throw IndexBatchException with no failures in IndexingResults
在我的微服务(负责根据事件消息将数据馈送到 Azure 搜索实例)中,我正在尝试 MergeOrUpload IndexBatch。批量大小始终为 1,因为一条事件消息仅包含一个我需要在搜索中合并或上传的实体。
我一直收到不包含 IndexingResults 的 IndexBatchException,其中 Succeeded 为 false。
Azure 搜索服务详细信息
- 等级:标准
- 分区和副本:3 & 3
微服务详情
- Asp .Net Core 版本: 2.2
- Microsoft.Azure.Search SDK 版本: 9.0.1
目前,我的代码已设置为通过在未来约 5 秒内按计划交付在服务总线上重新排队消息来处理 IndexBatchException。收到此重新排队的消息后,我的代码拒绝处理此事件消息,因为它发现消息日期时间不晚于搜索实例中的数据。
我知道我可以将异常处理更改为仅在 IndexingResults 失败时重试,但我想了解 IndexBatchException 背后的真正原因,它不包含 IndexingResults,其中 Succeeded 为 false 以及什么社区会建议这样做吗?。请注意,操作本身是成功的,因为每次第一次尝试时都会上传数据。
我还可以确认 azure 搜索实例没有负载并且没有超过它的任何限制。
代码示例
/// <inheritdoc />
public async Task ProcessDocument(DomainEvent<TMessage> domainEvent)
{
Guard.IsNotNull(domainEvent, nameof(domainEvent));
var searchIndexClient = await searchIndexClientFactory.CreateAsync(
domainEvent.TenantId,
IndexName);
var storedDocument = await GetDocument(
searchIndexClient,
domainEvent);
if (storedDocument != null && ValidateEventDate(domainEvent, storedDocument))
{
logger.LogWarning($"Received event but detected that more recent updates have already been applied. Incoming Event Details: {JsonConvert.SerializeObject(domainEvent)}");
return;
}
var newDocument = mapper.Map<TDocumentIndex>(domainEvent.Resource);
SetSomeProperties(domainEvent, newDocument); // Changed method name. It basically is adding some contextual prop's to doc
try
{
var documents = new TDocumentIndex[] { newDocument };
var batch = IndexBatch.MergeOrUpload(documents);
var result = await searchIndexClient
.Documents
.IndexAsync(batch);
var operationResult = result
.Results
.FirstOrDefault();
if (operationResult == null || operationResult.Succeeded == false)
{
logger.LogError($"There was an error when merging or uploading a document for tenant {domainEvent.TenantId}. Error message {operationResult?.ErrorMessage}, Message body {JsonConvert.SerializeObject(domainEvent)}");
}
}
catch (IndexBatchException indexBatchException)
{
logger.LogError($"Failed to index some of the documents: {0}", string.Join(", ", indexBatchException.IndexingResults.Where(r => !r.Succeeded).Select(r => $"{r.Key}:{r.ErrorMessage}")));
throw;
}
}
示例错误日志
- 无法索引某些文档:0
以上是通过以下代码行生成的
catch (IndexBatchException indexBatchException)
{
logger.LogError($"Failed to index some of the documents: {0}", string.Join(", ", indexBatchException.IndexingResults.Where(r => !r.Succeeded).Select(r => $"{r.Key}:{r.ErrorMessage}")));
throw;
}
我希望仅在搜索处于负载状态时触发索引批处理异常,即使如此,我希望它会抛出此异常并产生一些失败的结果。
该服务正在按预期返回 IndexingResults,但您的代码中存在一个小错误。该错误的提示在 "Failed to index some of the documents: 0" 中返回的“0”中。如果代码按预期运行,它将是一个空字符串。您需要删除将 {0} 评估为 c# 表达式而不是字符串格式标记的字符串上的 $。
它应该是:
logger.LogError("Failed to index some of the documents: {0}", string.Join(", ", indexBatchException.IndexingResults.Where(r => !r.Succeeded).Select(r => $"{r.Key}:{r.ErrorMessage}")));
在我的微服务(负责根据事件消息将数据馈送到 Azure 搜索实例)中,我正在尝试 MergeOrUpload IndexBatch。批量大小始终为 1,因为一条事件消息仅包含一个我需要在搜索中合并或上传的实体。
我一直收到不包含 IndexingResults 的 IndexBatchException,其中 Succeeded 为 false。
Azure 搜索服务详细信息
- 等级:标准
- 分区和副本:3 & 3
微服务详情
- Asp .Net Core 版本: 2.2
- Microsoft.Azure.Search SDK 版本: 9.0.1
目前,我的代码已设置为通过在未来约 5 秒内按计划交付在服务总线上重新排队消息来处理 IndexBatchException。收到此重新排队的消息后,我的代码拒绝处理此事件消息,因为它发现消息日期时间不晚于搜索实例中的数据。
我知道我可以将异常处理更改为仅在 IndexingResults 失败时重试,但我想了解 IndexBatchException 背后的真正原因,它不包含 IndexingResults,其中 Succeeded 为 false 以及什么社区会建议这样做吗?。请注意,操作本身是成功的,因为每次第一次尝试时都会上传数据。
我还可以确认 azure 搜索实例没有负载并且没有超过它的任何限制。
代码示例
/// <inheritdoc />
public async Task ProcessDocument(DomainEvent<TMessage> domainEvent)
{
Guard.IsNotNull(domainEvent, nameof(domainEvent));
var searchIndexClient = await searchIndexClientFactory.CreateAsync(
domainEvent.TenantId,
IndexName);
var storedDocument = await GetDocument(
searchIndexClient,
domainEvent);
if (storedDocument != null && ValidateEventDate(domainEvent, storedDocument))
{
logger.LogWarning($"Received event but detected that more recent updates have already been applied. Incoming Event Details: {JsonConvert.SerializeObject(domainEvent)}");
return;
}
var newDocument = mapper.Map<TDocumentIndex>(domainEvent.Resource);
SetSomeProperties(domainEvent, newDocument); // Changed method name. It basically is adding some contextual prop's to doc
try
{
var documents = new TDocumentIndex[] { newDocument };
var batch = IndexBatch.MergeOrUpload(documents);
var result = await searchIndexClient
.Documents
.IndexAsync(batch);
var operationResult = result
.Results
.FirstOrDefault();
if (operationResult == null || operationResult.Succeeded == false)
{
logger.LogError($"There was an error when merging or uploading a document for tenant {domainEvent.TenantId}. Error message {operationResult?.ErrorMessage}, Message body {JsonConvert.SerializeObject(domainEvent)}");
}
}
catch (IndexBatchException indexBatchException)
{
logger.LogError($"Failed to index some of the documents: {0}", string.Join(", ", indexBatchException.IndexingResults.Where(r => !r.Succeeded).Select(r => $"{r.Key}:{r.ErrorMessage}")));
throw;
}
}
示例错误日志
- 无法索引某些文档:0 以上是通过以下代码行生成的
catch (IndexBatchException indexBatchException)
{
logger.LogError($"Failed to index some of the documents: {0}", string.Join(", ", indexBatchException.IndexingResults.Where(r => !r.Succeeded).Select(r => $"{r.Key}:{r.ErrorMessage}")));
throw;
}
我希望仅在搜索处于负载状态时触发索引批处理异常,即使如此,我希望它会抛出此异常并产生一些失败的结果。
该服务正在按预期返回 IndexingResults,但您的代码中存在一个小错误。该错误的提示在 "Failed to index some of the documents: 0" 中返回的“0”中。如果代码按预期运行,它将是一个空字符串。您需要删除将 {0} 评估为 c# 表达式而不是字符串格式标记的字符串上的 $。
它应该是:
logger.LogError("Failed to index some of the documents: {0}", string.Join(", ", indexBatchException.IndexingResults.Where(r => !r.Succeeded).Select(r => $"{r.Key}:{r.ErrorMessage}")));