Cosmos DB(在 Azure 和 Fabric 中)通过本机 JSON 数据模型提供架构灵活性和丰富的索引。 所有 Cosmos DB 资源(包括数据库、容器、文档和存储过程)都建模并存储为 JSON 文档。 作为可移植的要求,JSON(和 Cosmos DB)仅支持一小组基本类型:字符串、数字、布尔值、数组、对象和 Null。 但是,JSON 非常灵活,允许开发人员和框架使用这些基元来表示更复杂的类型,并将其组合为对象或数组。
除了基本类型,许多应用程序还需要该 DateTime 类型来表示日期和时间信息。 本文介绍了开发人员如何使用 .NET SDK 在 Cosmos DB 中存储、检索和查询日期。
Store DateTimes
Cosmos DB 支持 JSON 类型,例如 - 字符串、数字、布尔值、null、数组、对象。 它不支持直接支持类型 DateTime 。 目前,NoSQL API 不支持日期本地化。 因此,必须将日期和时间信息存储为字符串。 日期和时间字符串的建议格式遵循 yyyy-MM-ddTHH:mm:ss.fffffffZISO 8601 UTC 标准。 将所有日期存储在 Cosmos DB 中作为 UTC。 将日期字符串转换为此格式允许按字典方式对日期进行排序。 如果存储非 UTC 日期,则必须在客户端处理逻辑。 若要将本地日期和时间值转换为 UTC,偏移量必须已知/存储为 JSON 中的属性,并且客户端可以使用偏移量来计算 UTC 日期和时间值。
仅当日期和时间字符串全部采用 UTC 时,才支持将日期和时间字符串作为筛选器的范围查询。
GetCurrentDateTime 系统函数以以下格式返回当前 UTC 日期和时间 ISO 8601 字符串值: yyyy-MM-ddTHH:mm:ss.fffffffZ
由于以下原因,大多数应用程序可以使用默认字符串表示形式 DateTime :
- 可以比较字符串,当日期/时间值的相对顺序转换为字符串时保留这些值。
- 此方法不需要任何自定义代码或属性进行 JSON 转换。
- JSON 中存储的日期是可读的。
- 此方法可以利用索引来实现快速查询性能。
例如,以下代码片段存储一个包含两Order个DateTime属性的对象,ShipDate并使用 OrderDate .NET SDK 作为文档:
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
}
``
Alternatively, you can store DateTimes as Unix timestamps, that is, as a number representing the number of elapsed seconds since **January 1, 1970**. Cosmos DB's internal timestamp (`_ts`) property follows this approach. You can use the [`UnixDateTimeConverter`](https://learn.microsoft.com/dotnet/api/microsoft.azure.documents.unixdatetimeconverter) class to serialize dates and times as numbers.
## Query date and time in LINQ
The .NET SDK automatically supports querying data stored using Language Integrated Query (LINQ). For example, the following snippet shows a LINQ query that filters orders that were shipped in the last three days:
```csharp
IQueryable<Order> orders = container
.GetItemLinqQueryable<Order>(allowSynchronousQueryExecution: true)
.Where(o => o.ShipDate >= DateTime.UtcNow.AddDays(-3));
LINQ 查询将转换为以下 SQL 语句并在 Cosmos DB 上执行:
SELECT
*
FROM
root
WHERE
(root["ShipDate"] >= "2014-09-30T23:14:25.7251173Z")
有关查询语言和 LINQ 提供程序的详细信息,请参阅 LINQ to SQL 翻译。
为范围查询编制索引日期和时间
查询通常与 DateTime 值一起使用。 若要有效地执行这些查询,必须在查询筛选器中的任何属性上定义索引。
有关如何配置索引策略的详细信息,请参阅 索引策略。