{"id":384,"date":"2019-01-14T13:06:05","date_gmt":"2019-01-14T04:06:05","guid":{"rendered":"https:\/\/162.43.49.248\/blog\/?p=384"},"modified":"2019-01-26T14:18:00","modified_gmt":"2019-01-26T05:18:00","slug":"azure-cosmos-db%e3%81%ab%e3%82%b9%e3%83%88%e3%82%a2%e3%83%89%e3%83%97%e3%83%ad%e3%82%b7%e3%83%bc%e3%82%b8%e3%83%a3%e3%81%8b%e3%82%89%e3%83%91%e3%83%bc%e3%83%86%e3%82%a3%e3%82%b7%e3%83%a7%e3%83%b3","status":"publish","type":"post","link":"https:\/\/yujiro.work\/blog\/?p=384","title":{"rendered":"Azure Cosmos DB\u306b\u30b9\u30c8\u30a2\u30c9\u30d7\u30ed\u30b7\u30fc\u30b8\u30e3\u304b\u3089\u30d1\u30fc\u30c6\u30a3\u30b7\u30e7\u30f3\u30ad\u30fc\u3092\u6307\u5b9a\u3057\u3066\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u8ffd\u52a0\u3059\u308b(C#)"},"content":{"rendered":"\n<p>Azure Cosmos DB\u3092SQL(document)\u3067\u4f5c\u6210\u3059\u308c\u3070\u666e\u901a\u306eSQL\u6587\u3067CRUD\u3067\u304d\u308b\u306e\u3067\u306f\u306a\u3044\u304b\u3068\u601d\u3044\u307e\u3057\u305f\u304c\u3001\u3069\u3046\u3084\u3089\u305d\u3046\u3067\u306f\u306a\u304f\u4f7f\u3048\u308b\u306e\u306fSELECT\u3001\u3057\u304b\u3082GROUP BY\u3082\u3067\u304d\u306a\u3044\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30b9\u30b3\u30fc\u30d7\u3082\u9069\u7528\u3055\u308c\u306a\u3044\u3068\u3044\u3046\u975e\u5e38\u306b\u7656\u306e\u3042\u308b\u4ee3\u7269\u3067\u3057\u305f\u3002\u30aa\u30fc\u30eb\u30c9\u30bf\u30a4\u30d7\u306b\u306f\u306a\u304b\u306a\u304b\u99b4\u67d3\u3081\u306a\u3044\u3067\u3059\u306d\u3002<\/p>\n\n\n\n<p>\u7279\u306b\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u30b9\u30b3\u30fc\u30d7\u306f\u9762\u5012\u3067\u3001\u30b9\u30c8\u30a2\u30c9\u30d7\u30ed\u30b7\u30fc\u30b8\u30e3\u3092\u7d4c\u7531\u3059\u308c\u3070\u30d1\u30fc\u30c6\u30a3\u30b7\u30e7\u30f3\u5358\u4f4d\u3067\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u304c\u4fdd\u8a3c\u3055\u308c\u308b\u3068\u3044\u3046\u3082\u306e\u3067\u3059\u3002\u3061\u306a\u307f\u306b\u30b9\u30c8\u30a2\u30c9\u30d7\u30ed\u30b7\u30fc\u30b8\u30e3\u306e\u5b9f\u88c5\u65b9\u6cd5\u306f\u306fAzure\u30dd\u30fc\u30bf\u30eb\u4e0a\u306b\u3066JavaScript\u306b\u3088\u308a\u5b9a\u7fa9\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u4ed5\u65b9\u304c\u306a\u3044\u3068\u8ae6\u3081\u3001\u30d9\u30bf\u66f8\u304d\u3067JavaScript\u3092\u66f8\u3044\u3066\u30b9\u30c8\u30a2\u30c9\u30d7\u30ed\u30b7\u30fc\u30b8\u30e3\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002\u30c6\u30b9\u30c8\u30c7\u30fc\u30bf\u3067\u306f&#8221;uniqid&#8221;\u3067\u30d1\u30fc\u30c6\u30a3\u30b7\u30e7\u30f3\u5316\u3055\u308c\u305f\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u3092\u60f3\u5b9a\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ SAMPLE STORED PROCEDURE\n\/\/ ID\u300cInsertDocuments\u300d\u3068\u3057\u3066\u30dd\u30fc\u30bf\u30eb\u4e0a\u304b\u3089\u767b\u9332\u3057\u307e\u3059\n\/\/\n\/\/ \u5f15\u6570 documents : JSON\u914d\u5217\u5f62\u5f0f\u306e\u6587\u5b57\u5217\n\/\/ \u623b\u5024 \u4f5c\u6210\u3057\u305f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306e\u914d\u5217\nfunction\u00a0InsertDocuments(documents) {\n    const\u00a0collection = getContext().getCollection();\n    const collLink = collection.getSelfLink();\n    console.log(\"documents=\" + documents +\"\\n\");\n    let jsonList;\n    try {\n        jsonList = JSON.parse(documents);\n    } catch(e) {\n        console.log(e);\n        return null;\n    }\n\n    console.log(\"length=\" + jsonList.length +\"\\n\");\n    let createdList = [];\n    for(let i=0 ; i&lt;jsonList.length ; i++){\n        let doc = jsonList[i];\n\n        \/\/ Query documents and tolist processed documents.\n        let\u00a0isAccepted = \n            collection.createDocument(\n                    collLink, \n                    doc, \n                    function (err, document) {\n                if (err) {\n                    console.log(err);\n\n                } else {\n                    console.log(\"created \" + document.id + \"\\n\");\n                    createdList.push(document);\n                    if(i==jsonList.length-1){\n                        getContext().getResponse().setBody(JSON.stringify(createdList));\n                    }\n                }\n            });\n        if\u00a0(!isAccepted)\u00a0throw\u00a0new\u00a0Error('The query was not accepted by the server.');\n    }\n\n    return;\n}<\/pre>\n\n\n\n<p>\u6b21\u306b\u5229\u7528\u5074\u306e\u30b3\u30fc\u30c9\u3092\u66f8\u304d\u307e\u3059\u3002\u4eca\u56de\u3001Functions V2(.NET Core)\u304b\u3089C#\u3092\u5229\u7528\u3057\u3066Cosmos DB\u306b\u30a2\u30af\u30bb\u30b9\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System;\nusing System.IO;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Azure.WebJobs;\nusing Microsoft.Azure.WebJobs.Extensions.Http;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.Logging;\nusing Newtonsoft.Json;\nusing Microsoft.Azure.Documents;\nusing Microsoft.Azure.Documents.Client;\nusing Newtonsoft.Json.Converters;\nusing System.Collections.Generic;\n\nnamespace FunctionsTest\n{\n    public static class FuncInsertDocument\n    {\n        private static readonly string EndpointUrl = \"&lt;your endpoint URL>\";\n        private static readonly string PrimaryKey = \"&lt;your primary key>\";  \/\/[Read-only Keys]\u3067\u554f\u984c\u306a\u3044\n        private static readonly string DataBaseId = \"&lt;your DataBase ID>\";\n        private static readonly string CollectionId = \"&lt;your Collection ID>\";\n\n        [FunctionName(\"FuncInsertDocument\")]\n        public static async Task&lt;IActionResult> Run(\n            [HttpTrigger(AuthorizationLevel.Function, \"get\", \"post\", Route = null)] HttpRequest req,\n            ILogger log)\n        {\n            log.LogInformation(\"C# HTTP trigger function processed a request.\");\n            DocumentClient client = new DocumentClient(new Uri(EndpointUrl), PrimaryKey);\n\n            \/\/ \u66f8\u8fbc\u30c7\u30fc\u30bf\u4f5c\u6210\n            var partitionKeyValue = \"U001\";\n            var dataList = new List&lt;TestData>();\n            dataList.Add(new TestData{\n                UniqId = partitionKeyValue,\n                SessionId = \"SES001\",\n                Time = new DateTimeOffset(new DateTime(2018,1,15,0,0,0,DateTimeKind.Local))\n            });\n\n            \/\/ \u30b9\u30c8\u30a2\u30c9\u30d7\u30ed\u30b7\u30fc\u30b8\u30e3\"InsertDocuments\"\u3092\u5b9f\u884c\u3059\u308b\n            Uri spUri = UriFactory.CreateStoredProcedureUri(\n                DataBaseId,\n                CollectionId,\n                \"InsertDocuments\");\n            string spParam = JsonConvert.SerializeObject(dataList);\n            RequestOptions options = new RequestOptions() {\n                EnableScriptLogging = true,\n                PartitionKey = new PartitionKey(partitionKeyValue)\n            };\n            var result = await client.ExecuteStoredProcedureAsync&lt;string>(\n              spUri,\n              options,\n              spParam);\n\n            \/\/ \u30af\u30a8\u30ea\u6210\u529f\u6642\u306b\u306f\u30b9\u30af\u30ea\u30d7\u30c8\u30ed\u30b0\u3092\u51fa\u529b\n            ActionResult ret = null;\n            if (result.Response != null) {\n                log.LogInformation(result.ScriptLog);\n                ret = new OkObjectResult($\"ret=\" + result.ScriptLog);\n            } else {\n                ret = new BadRequestObjectResult(\"Please pass a name on the query string or in the request body\");\n            }\n            return ret;\n        }\n    }\n\n    public class TestData {\n        [JsonProperty(\"uniqid\")]\n        public string UniqId {get;set;}\n\n        [JsonProperty(\"sessionid\")]\n        public string SessionId { get; set; }\n\n        [JsonProperty(\"time\")]\n        [JsonConverter(typeof(MyCustomDateTimeConverter))]\n        public DateTimeOffset Time { get; set; }\n    }\n\n    public class MyCustomDateTimeConverter : IsoDateTimeConverter {\n        public MyCustomDateTimeConverter() {\n            base.DateTimeFormat = \"yyyy-MM-dd'Z'HH:mm:ss'Z'\";\n        }\n    }\n}\n<\/pre>\n\n\n\n<p>\u6307\u5b9a\u3057\u305f\u30d1\u30fc\u30c6\u30a3\u30b7\u30e7\u30f3\u30ad\u30fc\u5024\u3068\u6295\u5165\u30c7\u30fc\u30bf\u306e\u5024\u304c\u4e00\u81f4\u3057\u306a\u3044\u5834\u5408\u306f\u30b9\u30c8\u30a2\u30c9\u30d7\u30ed\u30b7\u30fc\u30b8\u30e3\u306e\u547c\u3073\u51fa\u3057\u306f\u5931\u6557\u3057\u307e\u3059\u3002\u3088\u3063\u3066\u5b9f\u969b\u306e\u5229\u7528\u306b\u3042\u305f\u3063\u3066\u306f\u6295\u5165\u524d\u306bLINQ\u304b\u3089\u30d1\u30fc\u30c6\u30a3\u30b7\u30e7\u30f3\u30ad\u30fc\u5358\u4f4d\u3067\u30b0\u30eb\u30fc\u30d7\u5316\u3092\u884c\u3044\u3001\u307e\u305f\u30b3\u30ec\u30af\u30b7\u30e7\u30f3\u306b\u4e3b\u30ad\u30fc(Primary Keys)\u8a2d\u5b9a\u3092\u884c\u3044\u3001\u30b9\u30c8\u30a2\u30c9\u30d7\u30ed\u30b7\u30fc\u30b8\u30e3\u5074\u306b\u4e3b\u30ad\u30fc\u91cd\u8907\u6642\u306e\u4f8b\u5916\u51e6\u7406\u306a\u3069\u3092\u5b9f\u88c5\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<p>\u306a\u304a\u30b9\u30c8\u30a2\u30c9\u30d7\u30ed\u30b7\u30fc\u30b8\u30e3\u3092\u7d4c\u7531\u3059\u308b\u8ffd\u52a0\u51e6\u7406\u306f\u975e\u5e38\u306b\u9045\u304f\u3001\u3042\u304f\u307e\u3067\u3082\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u5fc5\u8981\u3068\u3057\u305f\u5c11\u91cf\u30c7\u30fc\u30bf\u306e\u66f4\u65b0\u306a\u3069\u306b\u3057\u304b\u4f7f\u3048\u307e\u305b\u3093\u3002\u5927\u91cf\u30c7\u30fc\u30bf\u306e\u53d6\u8fbc\u306b\u306fBulkExecuter\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u5229\u7528\u3057\u3066\u4e00\u6c17\u306b\u8ffd\u52a0\/\u66f4\u65b0\u3092\u3084\u308b\u306e\u304c\u672c\u6765\u671b\u307e\u308c\u308b\u51e6\u7406\u306e\u3088\u3046\u3067\u3059(\u305f\u3060\u3057V1\u9650\u5b9a)\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Azure Cosmos DB\u3092SQL(document)\u3067\u4f5c\u6210\u3059\u308c\u3070\u666e\u901a\u306eSQL\u6587\u3067CRUD\u3067\u304d\u308b\u306e\u3067\u306f\u306a\u3044\u304b\u3068\u601d\u3044\u307e\u3057\u305f\u304c\u3001\u3069\u3046\u3084\u3089\u305d\u3046\u3067\u306f\u306a\u304f\u4f7f\u3048\u308b\u306e\u306fSELECT\u3001\u3057\u304b\u3082GROUP BY\u3082\u3067\u304d\u306a\u3044\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7 [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"aside","meta":{"footnotes":""},"categories":[12],"tags":[31],"class_list":["post-384","post","type-post","status-publish","format-aside","hentry","category-12","tag-c","post_format-post-format-aside"],"_links":{"self":[{"href":"https:\/\/yujiro.work\/blog\/index.php?rest_route=\/wp\/v2\/posts\/384","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/yujiro.work\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yujiro.work\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yujiro.work\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/yujiro.work\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=384"}],"version-history":[{"count":5,"href":"https:\/\/yujiro.work\/blog\/index.php?rest_route=\/wp\/v2\/posts\/384\/revisions"}],"predecessor-version":[{"id":436,"href":"https:\/\/yujiro.work\/blog\/index.php?rest_route=\/wp\/v2\/posts\/384\/revisions\/436"}],"wp:attachment":[{"href":"https:\/\/yujiro.work\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=384"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yujiro.work\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=384"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yujiro.work\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=384"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}