【问题标题】:Azure.Search.Documents - Update or insert object with collectionsAzure.Search.Documents - 使用集合更新或插入对象
【发布时间】:2020-12-02 02:49:35
【问题描述】:

我需要添加带有子项的新文档或将子项添加到现有的父项。 我知道该怎么做的唯一方法是丑陋的:

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);
}

我认为如果这个文档不包含集合不会有任何问题。如果有子集合,则不能使用 MergeOrUpload。您需要从索引加载它们并添加元素。 有没有更好的办法?

【问题讨论】:

    标签: azure azure-cognitive-search azure-search-.net-sdk


    【解决方案1】:

    Azure Cognitive Search doesn't support partial updates to collection fields,因此检索整个文档、修改相关集合字段并将文档发送回索引是完成此操作的唯一方法。

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

    请注意,如果您拥有在索引时重建整个文档所需的所有数据,则可以跳过首先检索文档的步骤,这将是一个很大的改进。 Azure Cognitive Search doesn't yet support concurrency control 用于更新索引中的文档,所以最好还是让一个进程写入索引。这有望消除在更新和写回文档之前阅读文档的需要。这是假设您没有将搜索索引用作您的主要商店,即 really should avoid

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

    【讨论】:

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