在 Azure Cosmos DB for NoSQL 中处理日期
适用范围: NoSQL
Azure Cosmos DB for NoSQL 通过本机 JSON 数据模型提供架构灵活性和丰富的索引。 所有 Azure Cosmos DB 资源(包括数据库、容器、文档和存储过程)均作为 JSON 文档进行建模和存储。 为使代码可移植,JSON(及 Azure Cosmos DB)仅支持一小组基本类型:字符串、数字、布尔值、数组、对象和 Null。 但是,JSON 具有相当的灵活性,允许开发人员和框架使用这些基元并将其编写为对象或数组,以便表示更复杂的类型。
除了基本类型,许多应用程序还需要 DateTime
类型以表示日期和时间的类型。 本文介绍开发人员可如何使用 .NET SDK 在 Azure Cosmos DB 中存储、检索和查询日期。
存储 DateTime
Azure Cosmos DB 支持 JSON 类型,如字符串、数字、布尔值、null、数组和对象。 它不直接支持 DateTime
类型。 目前,API for NoSQL 不支持日期本地化。 因此,必须将日期和时间信息存储为字符串。 日期和时间字符串的建议格式为 yyyy-MM-ddTHH:mm:ss.fffffffZ
,它遵循 ISO 8601 UTC 标准。 建议以 UTC 格式存储 Azure Cosmos DB 中的所有日期。 将日期字符串转换为此格式允许按字典顺序对日期进行排序。 如果存储非 UTC 日期,则必须在客户端处理相关逻辑。 若要将本地日期和时间值转换为 UTC,偏移量必须已知/存储为 JSON 中的属性,并且客户端可以使用偏移量来计算 UTC 日期和时间值。
仅当日期和时间字符串全部采用 UTC 格式时,才支持使用日期和时间字符串作为筛选器的范围查询。 GetCurrentDateTime 系统函数会返回以下格式的当前 UTC 日期和时间 ISO 8601 字符串值:yyyy-MM-ddTHH:mm:ss.fffffffZ
。
由于以下原因,大多数应用程序可以使用 DateTime
的默认字符串表示形式:
- 字符串可以进行比较,而 DateTime 值的相对顺序在这些值转换为字符串时得以保留。
- 此方法不需要进行 JSON 转换所需的任何自定义代码或属性。
- 在 JSON 中存储的日期人工可读。
- 这种方法可以利用索引执行快速查询。
例如,以下代码片段使用 .NET SDK 将 Order
对象存储为文档,该对象包含两个 DateTime
属性 - ShipDate
和 OrderDate
:
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 = "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
OrderDate = DateTime.UtcNow.AddDays(-30),
ShipDate = DateTime.UtcNow.AddDays(-14),
Total = 113.39
});
本文档存储在以下结构中:
{
"id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
"OrderDate": "2014-09-15T23:14:25.7251173Z",
"ShipDate": "2014-09-30T23:14:25.7251173Z",
"Total": 113.39
}
也可将 DateTime 存储为 Unix 时间戳,即存储为数字,用于表示自 1970 年 1 月 1 日以来已过去的秒数。 Azure Cosmos DB for NoSQL 的内部时间戳 (_ts
) 属性遵循这种方法。 可以使用 UnixDateTimeConverter
类将日期和时间序列化为数字。
在 LINQ 中查询日期和时间
.NET SDK 自动支持使用语言集成查询 (LINQ) 查询存储的数据。 例如,以下代码片段显示一个 LINQ 查询,该查询筛选在过去三天内发运的订单:
IQueryable<Order> orders = container
.GetItemLinqQueryable<Order>(allowSynchronousQueryExecution: true)
.Where(o => o.ShipDate >= DateTime.UtcNow.AddDays(-3));
LINQ 查询将转换为以下 SQL 语句,并在 Azure Cosmos DB 上执行:
SELECT
*
FROM
root
WHERE
(root["ShipDate"] >= "2014-09-30T23:14:25.7251173Z")
有关查询语言和 LINQ 提供程序的详细信息,请参阅 LINQ to SQL 翻译。
为范围查询编制索引日期和时间
查询通常使用 DateTime
值。 若要高效执行这些查询,必须已在查询筛选器中的任何属性上定义索引。
有关如何配置索引策略的详细信息,请参阅 索引策略。