2017-02-02 6 views
3

Azure関数に関する私のprevious postに続く質問。私は、必須バインダー(バインダー)を使用してDocumentDB内の文書を更新する必要があります。私はdocumentationを実際に理解しておらず、例を見つけることができません(多かれ少なかれ、TextWriterの例の1つを見つける)。ドキュメンテーションは、私が "out T"にバインドすることができると言います。これについての例は見つかりません。Azure関数バインダーを使用したDocumentDbドキュメントの更新

{ 
    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でOutputを追加しようとしましたが、コンパイラはそれに不満を持ち、ドキュメンテーションはあなたが何も持ってはいけないと述べています。

私には何が欠けていますか?

+0

@mathewcを今日あなたのために。しかし、コンパイラのエラーを見たときにあなたのfunction.jsonがどのように見えるかを共有できますか?私は出力バインディングを使用して更新を実行できるはずだと信じています。パラメータとして 'IAsyncCollector collector'を使用し、' collector.AddAsync(document) 'を呼び出す必要があります。私はサンプルをセットアップし、それを – brettsam

+0

の下に投稿しようとします。コンパイルエラーは、アウトの引数として出力が実行時に欠落していたことでした。しかし、私はこのブログの投稿に従って試しました:https://weblogs.asp.net/sfeldman/azure-functions-to-make-audit-queue-and-auditors-happyここで彼は出力を宣言していないようですアウトの議論。 – Kimmen

答えて

5

マシューのサンプルが動作しますが、私はあなたがBinderと出力結合でそれを行うことができ、他の方法を明確にしたかったです。あなたは二つの問題にぶつかっている

  1. ダイナミックのDocument実装では、新しいオブジェクトインスタンスにあなたが子オブジェクトを要求するたびに返すように表示されます。これは関数とは関係ありませんが、document.child.value = 200が機能しない理由を説明しています。実際に文書に添付されていない子インスタンスを1つ更新しています。私はDocumentDbの人々とこれを再確認しようとしますが、それは混乱しています。これを回避する方法の1つは、dynamicの代わりにJObjectをリクエストすることです。私のコードは以下の通りです。

  2. @mathewcが指摘したように、Binderはドキュメントを自動更新しません。我々は彼が提出した問題でそれを追跡します。代わりに、IAsyncCollector<dynamic>の出力バインディングを使用してドキュメントを更新することができます。舞台裏では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 
} 
+0

これは適切な回避策です。ありがとうございます。以前はIAsyncCollector型を調べていましたが、Updateメソッドを探していて、AddAsyncを調べていませんでした。それは少し誤解を招く名前ですが、私はこれがドキュメントを更新する適切な方法ではないと思います。 – Kimmen

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を使用していると、それはかもしれませんあなたはあなたのすべての操作、あなたの呼び出しのためにそれを直接使うことができます。例えば:(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); 
} 
+1

今回は、以下の@brettsamの解決策を検討します。しかし、DocumentClientを使用してシナリオを照会するのは面白いと思いますが、これは将来的に使用する可能性が高いシナリオです。 Binderの代わりにDocumentClientを使用する際の賛否両論は何ですか(Binderの問題が解決されたら)? – Kimmen

関連する問題