怎么把Mongo changestream的BSON Timestamp转换成日期?

时间:2019-06-07 07:44:12

标签: mongodb

我在Mongo中开始使用Changestream。在我当前的设置中,stitch函数将changelog事件插入到修订集中。但是,当我从集合中读取数据时,无法转换Timestamp字段。我尝试了以下2次尝试:

1)管道

[
    {
        $match: {
            'documentKey._id': _id,
        },
    },
    {
        $sort: { _id: -1 },
    },
    {
        $addFields: {
            convertedDate: { $toDate: 'clusterTime' },
        },
    },
]

但是它给出了错误:Error parsing date string 'clusterTime'; 0: passing a time zone identifier as part of the string is not allowed 'c'; 6: Double timezone specification 'r'

2)bson Timestamp类

import { Timestamp } from 'bson';
const asTimestampInstance = new Timestamp(v.clusterTime);

但是这里的打字稿给了我错误:Expected 2 arguments, but got 1.ts(2554) index.d.ts(210, 30): An argument for 'high' was not provided.

在Altas中,群集时间正确地看起来像是一个时间戳记:

Screenshot of data in Atlas

我希望我只是缺少一些简单的方法:)

2 个答案:

答案 0 :(得分:3)

2) The bson Timestamp class

您应该从 BSON 的 Timestamp 类实例中获取第一个 32 位值,表示秒 Epoch time,然后将秒乘以 1000 并使其成为纪元时间的毫秒,然后调用 JS 日期构造函数。

如果 v 是来自 ChangeStream 的文档,v.clusterTime 是 BSON Timestamp 类对象。所以,你应该写:

const date = new Date(v.clusterTime.getHighBits() * 1000);

这个例子在 MongoDB 4.0、ODM Mongoose 5.12、Node.js 12 上对我有用。

答案 1 :(得分:2)

不幸的是,$toDate不能直接用于时间戳。至少在v4.0中没有。

参数应该是数字,字符串或ObjectId。

您需要先将时间戳记转换为字符串:

    $addFields: {
        convertedDate: { $toDate: {$dateToString:{date:"$clusterTime"}} },
    },