【问题标题】:Azure Functions Update DocumentDb document with BinderAzure Functions 使用 Binder 更新 DocumentDb 文档
【发布时间】:2017-02-02 16:23:49
【问题描述】:

我的previous post 关于 Azure Functions 的后续问题。我需要使用命令式活页夹 (Binder) 更新 DocumentDB 中的文档。我不太了解documentation,也找不到任何示例(我或多或少找到了一种示例,即 TextWriter 示例)。文档说我可以绑定到“out T”,因为我找不到这样的例子。

在运行函数之前假设文档是这样的:

{
    child: {
        value: 0
    }
}

函数看起来像这样:

var document = await binder.BindAsync<dynamic>(new DocumentDBAttribute("myDB", "myCollection")
{
    ConnectionStringSetting = "my_DOCUMENTDB",
    Id = deviceId
});

log.Info($"C# Event Hub trigger function processed a message: document: { document }");

document.value = 100;
document.child.value = 200;

log.Info($"Updated document: { document }");

根据第二个日志记录行,文档没有正确更新。子代未更新(从存储中读取时已存在)并添加了值。无论哪种方式,都没有持久化。我尝试在 function.json 中添加一个输出,但编译器抱怨它并且文档声明你不应该有任何。

我错过了什么?

【问题讨论】:

  • @mathewc 在下面提到,这种情况今天不会为您自动更新。但是,当您看到编译器错误时,您能分享一下您的 function.json 的样子吗?我相信您应该能够使用输出绑定来执行更新——您必须使用IAsyncCollector&lt;dynamic&gt; collector 作为参数,然后调用collector.AddAsync(document)。我会尝试设置一个示例并将其发布在下面
  • 编译错误是运行签名中缺少输出作为输出参数,这与预期的一样。但我根据这篇博文进行了尝试:weblogs.asp.net/sfeldman/… 他似乎在没有将它作为输出参数的情况下声明了一个输出。

标签: azure azure-cosmosdb azure-functions


【解决方案1】:

Mathew 的示例(使用 DocumentClient)有效,但我想澄清您可以使用 Binder 和输出绑定的另一种方式。

您遇到了两个问题:

  1. 动态的Document 实现似乎在您每次请求子对象时都返回一个新对象实例。这与函数无关,但解释了为什么 document.child.value = 200 不起作用。您正在更新一个实际未附加到文档的子实例。我将尝试与 DocumentDb 人员仔细检查这一点,但这令人困惑。解决此问题的一种方法是请求JObject 而不是dynamic。我下面的代码就是这样做的。

  2. 正如@mathewc 指出的那样,Binder 不会自动更新文档。我们将在他提交的问题中进行跟踪。相反,您可以使用带有IAsyncCollector&lt;dynamic&gt; 的输出绑定来更新文档。在幕后,我们将调用 InsertOrReplaceDocumentAsync,这将更新文档。

这是一个对我有用的完整示例:

代码:

#r "Microsoft.Azure.WebJobs.Extensions.DocumentDB"
#r "Newtonsoft.Json"

using System;
using Newtonsoft.Json.Linq;

public static async Task Run(string input, Binder binder, IAsyncCollector<dynamic> collector, TraceWriter log)
{        
    string deviceId = "0a3aa1ff-fc76-4bc9-9fe5-32871d5f451b";
    dynamic document = await binder.BindAsync<JObject>(new DocumentDBAttribute("ItemDb", "ItemCollection")
    {
        ConnectionStringSetting = "brettsamfunc_DOCUMENTDB",
        Id = deviceId
    });

    log.Info($"C# Event Hub trigger function processed a message: document: { document }");

    document.value = 100;
    document.child.value = 200;

    await collector.AddAsync(document);
    log.Info($"Updated document: { document }");
}

绑定:

{
  "type": "documentDB",
  "name": "collector",
  "connection": "brettsamfunc_DOCUMENTDB",
  "direction": "out",
  "databaseName": "ItemDb",
  "collectionName": "ItemCollection",
  "createIfNotExists": false
}

【讨论】:

  • 这是一个合适的解决方法,非常感谢。我之前正在查看 IAsyncCollector 类型,但我正在寻找一个 Update 方法并且没有调查 AddAsync。虽然这个名字有点误导人,但我想这不是更新文档的正确方法。
【解决方案2】:

是的,我确实认为这里存在问题,并且我在我们的存储库中记录了一个错误 here 以跟踪它。

要在我们修复它之前解决这个问题,您可以直接绑定并使用DocumentClient 来执行更新,例如:

public static async Task Run(
    string input, Binder binder, DocumentClient client, TraceWriter log)
{
    var docId = "c31d48aa-d74b-46a3-8ba6-0d4c6f288559";
    var document = await binder.BindAsync<JObject>(
                new DocumentDBAttribute("ItemDb", "ItemCollection")
    {
        ConnectionStringSetting = "<mydb>",
        Id = docId
    });

    log.Info("Item before: " +  document.ToString());
    document["text"] = "Modified!";

    var docUri = UriFactory.CreateDocumentUri("ItemDb", "ItemCollection", docId);
    await client.ReplaceDocumentAsync(docUri, document);
}

然而,一旦你像这样直接使用DocumentClient,你可能会发现你可以直接将它用于你的所有操作,你的电话。例如:

public static async Task Run(
    string input, DocumentClient client, TraceWriter log)
{
    var docId = "c31d48aa-d74b-46a3-8ba6-0d4c6f288559";
    var docUri = UriFactory.CreateDocumentUri("ItemDb", "ItemCollection", docId);

    var response = await client.ReadDocumentAsync(docUri);
    dynamic document = response.Resource;

    log.Info("Value: " +  dynamic.text);
    document.text = "Modified!"; 

    await client.ReplaceDocumentAsync(docUri, document);
}

【讨论】:

  • 这次我要从下面的@brettsam 寻求解决方案。但是我想使用 DocumentClient 来查询场景很有趣,我将来更有可能使用它。使用 DocumentClient 代替 Binder 的优缺点是什么(一旦 Binder 的问题得到解决)?
猜你喜欢
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
相关资源
最近更新 更多