Azure Cosmos DB で日付を扱う
適用対象: SQL API
Azure Cosmos DB は、ネイティブの JSON データ モデルにより、スキーマの柔軟性と豊富なインデックス機能を提供します。 データベース、コンテナー、ドキュメント、ストアド プロシージャを含むすべての Azure Cosmos DB リソースは、JSON ドキュメントとしてモデル化されて保存されます。 ポータブルであることが求められる JSON (および Azure Cosmos DB) では、少数の基本的な型 (String、Number、Boolean、Array、Object、Null) しかサポートされません。 ただし、JSON は柔軟性が高いため、開発者およびフレームワークは、これらのプリミティブ型を使用したり、オブジェクトまたは配列として作成したりすることにより、複雑な型を表現できます。
基本の型の他に、多くのアプリケーションでは日付やタイムスタンプを表す DateTime 型が必要です。 この記事では、開発者が、.NET SDK を使用して Azure Cosmos DB で日付の格納、取得、クエリを行う方法を説明します。
DateTimes の格納
Azure Cosmos DB は、string、number、boolean、null、array、object などの JSON 型をサポートしています。 DateTime 型は直接サポートされません。 現在、Azure Cosmos DB では、日付のローカリゼーションはサポートされません。 そのため、DateTimes を文字列として格納する必要があります。 Azure Cosmos DB の DateTime 文字列に推奨される形式は、ISO 8601 UTC 標準に準拠した yyyy-MM-ddTHH:mm:ss.fffffffZ
です。 Azure Cosmos DB のすべての日付を UTC として格納することをお勧めします。 日付文字列をこの形式に変換すると、日付を辞書式で並べ替えることができます。 UTC 以外の日付が格納されている場合は、クライアント側でロジックを処理する必要があります。 現地の DateTime を UTC に変換するには、オフセットが JSON のプロパティとして認識および格納されている必要があります。また、クライアントでオフセットを使用して UTC の DateTime 値を計算できます。
DateTime 文字列をフィルターとして使用する範囲クエリは、DateTime 文字列がすべて UTC にあり、長さが同じ場合にのみサポートされます。 Azure Cosmos DB では、GetCurrentDateTime システム関数は、yyyy-MM-ddTHH:mm:ss.fffffffZ
の形式で現在の UTC 日時 ISO 8601 文字列値を返します。
ほとんどのアプリケーションは、次に示す理由から、DateTime の既定の文字列表現を使用できます。
- 文字列は比較することができます。DateTime 値が文字列に変換されるとき、値の相対的な順序は維持されます。
- この方法では、JSON 変換のためのカスタム コードまたは属性は必要ありません。
- JSON に格納されている日付を人間が判読できます。
- この方法では、高速クエリ パフォーマンスのために Azure Cosmos DB のインデックスを利用できます。
たとえば、次のスニペットは、.NET SDK を使用して 2 つの DateTime プロパティ (ShipDate
と OrderDate
) を含むOrder
オブジェクトをドキュメントとして格納します。
public class Order
{
[JsonProperty(PropertyName="id")]
public string Id { get; set; }
public DateTime OrderDate { get; set; }
public DateTime ShipDate { get; set; }
public double Total { get; set; }
}
await container.CreateItemAsync(
new Order
{
Id = "09152014101",
OrderDate = DateTime.UtcNow.AddDays(-30),
ShipDate = DateTime.UtcNow.AddDays(-14),
Total = 113.39
});
このドキュメントは、Azure Cosmos DB に次のように格納されます。
{
"id": "09152014101",
"OrderDate": "2014-09-15T23:14:25.7251173Z",
"ShipDate": "2014-09-30T23:14:25.7251173Z",
"Total": 113.39
}
または、DateTimes を Unix タイムスタンプ (1970 年 1 月 1 日からの経過秒数を表す数値) として格納することもできます。 Azure Cosmos DB の内部 Timestamp (_ts
) プロパティは、この方法を使用しています。 UnixDateTimeConverter クラスを使用して、DateTime を数値としてシリアル化できます。
LINQ での DateTime のクエリ
SQL .NET SDK は、LINQ 経由で Azure Cosmos DB に格納されたデータのクエリを自動的にサポートします。 たとえば、次のスニペットは、3 日以内に出荷された注文をフィルター処理する LINQ クエリです。
IQueryable<Order> orders = container.GetItemLinqQueryable<Order>(allowSynchronousQueryExecution: true).Where(o => o.ShipDate >= DateTime.UtcNow.AddDays(-3));
次の SQL ステートメントに変換され、Azure Cosmos DB で実行されます。
SELECT * FROM root WHERE (root["ShipDate"] >= "2014-09-30T23:14:25.7251173Z")
Azure Cosmos DB の SQL クエリ言語と LINQ プロバイダーについては、LINQ での Cosmos DB のクエリに関する記事を参照してください。
範囲クエリ用の DateTimes のインデックス作成
クエリは DateTime 値でよく使用されます。 これらのクエリを効率的に実行するには、クエリのフィルターのプロパティにインデックスが定義されている必要があります。
インデックス作成ポリシーを構成する方法の詳細については、「Azure Cosmos DB のインデックス作成ポリシー」を参照してください。
次の手順
- GitHub のコード サンプルのダウンロードと実行
- SQL クエリの詳細を確認する
- Azure Cosmos DB のインデックス作成ポリシーの詳細を確認する