Azure.Search.Documents-使用集合更新或插入对象

Azure.Search.Documents-使用集合更新或插入对象,azure,azure-cognitive-search,azure-search-.net-sdk,Azure,Azure Cognitive Search,Azure Search .net Sdk,我需要添加包含子文档的新文档,或者将子文档添加到现有的父文档中。 我知道怎么做的唯一方法是丑陋: public async Task AddOrUpdateCase(params) { try { await UpdateCase(params); } catch (RequestFailedException ex) { if (ex.Status != (int)HttpStatusCode.NotFound)

我需要添加包含子文档的新文档,或者将子文档添加到现有的父文档中。 我知道怎么做的唯一方法是丑陋:

public async Task AddOrUpdateCase(params)
{
    try
    {
        await UpdateCase(params);
    }
    catch (RequestFailedException ex)
    {
        if (ex.Status != (int)HttpStatusCode.NotFound)
           throw;

       await AddCase(params);
    }
}

private async Task UpdateCase(params)
{
    // this line throws when document is not found
    var caseResponse = await searchClient.GetDocumentAsync<Case>(params.CaseId) 
    // need to add to existing collection
    caseResponse.Value.Children.Add(params.child);
}
public异步任务AddOrUpdateCase(params)
{
尝试
{
等待更新状态(参数);
}
捕获(RequestFailedException ex)
{
如果(ex.Status!=(int)HttpStatusCode.NotFound)
投掷;
等待AddCase(params);
}
}
专用异步任务UpdateCase(参数)
{
//当找不到文档时,此行抛出
var casesponse=await searchClient.getdocumentsync(params.CaseId)
//需要添加到现有集合中
casesponse.Value.Children.Add(params.child);
}
我认为如果这份文件不包含收集,就不会有任何问题。如果存在子集合,则不能使用
MergeOrUpload
。您需要从索引中加载它们并添加元素。 有更好的方法吗?

,因此检索整个文档、修改相关的集合字段并将文档发送回索引是完成此操作的唯一方法

我建议对您展示的代码进行的唯一改进是搜索要更新的文档,而不是逐个检索它们。这样,您就可以批量更新它们。索引更新要比查询昂贵得多,所以为了减少开销,您应该尽可能将更新批处理在一起

请注意,如果您拥有在索引时重新构建整个文档所需的所有数据,则可以跳过首先检索文档的步骤,这将是一个很大的改进。用于更新索引中的文档,因此最好还是使用单个进程写入索引。这将有望消除在更新和写回文档之前阅读文档的需要。这是假设您没有使用搜索索引作为您的主存储,而您正在使用它


如果您需要经常在复杂集合中添加或更新项,这可能表明您的索引需要不同的数据模型。复杂集合具有(请参见“每个文档的所有复杂集合中的最大元素”),这使得它们在父子关系的基数较高的情况下不切实际。对于这种情况,最好有一个包含“子”实体作为顶级文档的二级索引,而不是复杂集合的元素。这不仅有利于增量更新,而且有利于存储利用率和安全性。

我总是只更新一个文档。一封到多封(不超过几封)电子邮件就是这种情况。因此,我创建了
Case
作为主文档,并将电子邮件作为嵌套集合。我将只添加到
电子邮件
收集和更新
案例
字段。我需要搜索电子邮件主题、正文、地址,并返回带有
电子邮件的
案例
。你觉得这个型号怎么样?我以前没有使用过Azure search。如果案例中没有多少详细信息不在电子邮件集合中,并且您计划频繁插入/更新单个电子邮件,我会使用非规范化模型,其中电子邮件是文档,每个电子邮件重复案例详细信息。另一方面,如果Case有很多这样的细节,并且它们经常更改,那么您当前的模型就更好了。如果我使用非规范化模型,每当
Case
字段更改时,我就必须更新属于
Case
的所有电子邮件?是的,因此这是一种折衷。如果
Case
字段和
email
字段都经常更新,你可以有两个索引,同时查询这两个索引,并在你的应用程序中对结果进行一种“客户端连接”,但你必须选择使用哪个相关性分数来排序结果(Case或email),而你可能想要的分数是同时考虑两者的分数。这里没有“一刀切”的解决方案。我在回答中添加了一段,解释了避免当前使用的读/修改/写模式的方法。希望这也有帮助。