Lagra och fråga datum – Frågespråk i Cosmos DB (i Azure och Fabric)

Cosmos DB (i Azure och Fabric) ger schemaflexisk flexibilitet och omfattande indexering via en intern JSON-datamodell . Alla Cosmos DB-resurser, inklusive databaser, containrar, dokument och lagrade procedurer, modelleras och lagras som JSON-dokument. Som ett krav för att vara portabel stöder JSON (och Cosmos DB) endast en liten uppsättning grundläggande typer: String, Number, Boolean, Array, Object och Null. JSON är dock flexibelt och gör det möjligt för utvecklare och ramverk att representera mer komplexa typer med hjälp av dessa primitiver och skapa dem som objekt eller matriser.

Förutom de grundläggande typerna behöver DateTime många program typen för att representera datum och tidsinformation. Den här artikeln beskriver hur utvecklare kan lagra, hämta och fråga efter datum i Cosmos DB med hjälp av .NET SDK.

Lagra DateTimes

Cosmos DB stöder JSON-typer som - sträng, tal, boolesk, null, matris, objekt. Den har inte direkt stöd för en DateTime typ. Api:et för NoSQL stöder för närvarande inte lokalisering av datum. Därför måste du lagra datum- och tidsinformation som strängar. Det rekommenderade formatet för datum- och tidssträngar är yyyy-MM-ddTHH:mm:ss.fffffffZ, vilket följer ISO 8601 UTC-standarden. Lagra alla datum i Cosmos DB som UTC. Om du konverterar datumsträngarna till det här formatet kan du sortera datum lexicographically. Om icke-UTC-datum lagras måste logiken hanteras på klientsidan. Om du vill konvertera ett lokalt datum- och tidsvärde till UTC måste förskjutningen vara känd/lagrad som en egenskap i JSON och klienten kan använda förskjutningen för att beräkna UTC-datum- och tidsvärdet.

Intervallfrågor med datum- och tidssträngar som filter stöds endast om datum- och tidssträngarna alla finns i UTC. Systemfunktionen GetCurrentDateTime returnerar det aktuella ISO 8601-strängvärdet FÖR UTC-datum och tid i formatet: yyyy-MM-ddTHH:mm:ss.fffffffZ.

De flesta program kan använda standardsträngrepresentationen DateTime av följande skäl:

  • Strängar kan jämföras och den relativa ordningen för DateTime-värdena bevaras när de omvandlas till strängar.
  • Den här metoden kräver ingen anpassad kod eller attribut för JSON-konvertering.
  • Datumen som lagras i JSON är läsbara för människor.
  • Den här metoden kan dra nytta av indexet för snabba frågeprestanda.

Följande kodfragment lagrar till exempel ett Order objekt som innehåller två DateTime egenskaper – ShipDate och OrderDate som ett dokument med hjälp av .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
    });

Det här dokumentet lagras i följande struktur:

{
  "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`](/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-frågan översätts till följande SQL-instruktion och körs på Cosmos DB:

SELECT
    *
FROM
    root
WHERE
    (root["ShipDate"] >= "2014-09-30T23:14:25.7251173Z")

Mer information om frågespråket och LINQ-providern finns i LINQ till SQL-översättning.

Indexdatum och tid för intervallfrågor

Frågor är vanliga med DateTime värden. Om du vill köra dessa frågor effektivt måste du ha ett index definierat på alla egenskaper i frågans filter.

Mer information om hur du konfigurerar indexeringsprinciper finns i indexeringsprinciper.