Cosmos DB has no type for a duration. System.Text.Json writes a TimeSpan as text, for example "2.00:00:00".
Cosmos DB compares text by character code. Thus "2.00:00:00" sorts after "10.00:00:00", and "23:00:00" sorts
after both. A query with ORDER BY or with > on such a field gives the wrong result.
TimeSpanTicksConverter writes the number of ticks instead. One tick is 100 nanoseconds. Cosmos DB sorts and
compares a number in time order.
Add the converter to the options of System.Text.Json. Then give the options to the client. The camel case naming
policy writes the field Id as id, which Cosmos DB requires:
|
Each TimeSpan that the client writes is now a number. This record is stored as the JSON below it:
|
|
The client writes a parameter with the same converter. Thus a query can compare the field with a TimeSpan:
|
The converter also handles Nullable<TimeSpan> and a TimeSpan as the key of a dictionary.
The converter reads the text that System.Text.Json writes, for example "1.02:00:00". Thus a container with old
documents stays readable. An old document keeps its text until you write it again. Cosmos DB sorts a number before a
text. Thus a query with ORDER BY returns the new documents in time order, then the old documents in the order of
their text. With DESC the two groups change places.
To move the old documents, read each one and write it again with a client that uses the converter.
UseSystemTextJsonSerializerWithOptions.TimeSpan can lose digits in a client that reads the number as
a floating-point number.
c.duration >= 36000000000 for one hour, or use a TimeSpan parameter as above.