To whom it may concern,
I’m trying to start getting changes from change streams given a date/time. There’s a handy parameter to “db.collection.watch()”, startAtOperationTime, that, in theory one could you to specify the date/time. One would think that one could extract a timestamp from a date. Heck, in a perfect world, one would provide the Date or ISODate as the “startAtOperationTime” value and it would just work. Nope, no auto coercion; this parameter value must be a Timestamp. It doesn’t help that there are multiple definitions of what a timestamp is.
Unfortunately, it is difficult to convert Date/IOSDate. You can’t simply use the output of $toLong aggregation operator. By the way, you could create a Date using that long, but curiously, not a ISODate. The “watch” operation wants a “timestamp” and complains if it gets something that isn’t one of those.
I attempted to step through the conversion using an aggregation pipeline
$ db.copyProgress.aggregate([
... {$match:{"_id": "csTestCopy"}},
... {
... "$project":{
... "_id":0,
... "startedEpoch":{
... "$toLong":"$started"
... }
... }
... },
... {
... "$project":
... {
... "startedTimeSeconds":
... {
... "$trunc": {
... $divide: [ "$startedEpoch", 100000 ]
... }
... }
... }
... },
... {
... "$project":{
... "startedTimestamp": new Timestamp( 1,
... { "$toInt":"$startedTimeSeconds" }
... )
... }
... }
... ])
2020-04-08T14:14:33.996-0500 E QUERY [js] Error: Timestamp increment must be a number :
@(shell):24:29
I added in the “$toInt” conversion hoping to get around this error, but this error goes deep.
So, what is the magic to have a Date/time and convert that into a Timestamp that “watch()” wants?
Regards,
Steve