2

我正在尝试在 Cassandra 中存储博客的评论并提出了这个模式(从这里得到想法):

create table comments ( slug varchar, ts timestamp, value text, primary key (slug,ts));

使用 CQL(我正在使用带有Helenus驱动程序的 node.js)我正在尝试向其中添加一些数据,这是我到目前为止所得到的:

var helenus = require('helenus'),
    pool = new helenus.ConnectionPool({
        hosts: ['localhost:9160'],
        keyspace: 'blogks'
    });

pool.on('error', function(err) {
    console.error(err.name, err.message);
});



module.exports.addComment = function(slug, comment,callback){
    pool.connect(function(connErr,keyspace){
        if(connErr){
            callback(connErr);
            return;
        }

        var cql = "INSERT INTO comments (slug,ts,value) VALUES (?, ?, ?);";
        pool.cql(cql,[slug,serializeDate(new Date()),serializeJSON(comment)],function(err,results){
            callback(err,results);
        });
    });
}

function serializeDate(date){
    var dateSerializer = new helenus.Marshal('DateType');
    return dateSerializer.serialize(date).toString('hex');
}

function serializeJSON(data){
    var utf8Serializer = new helenus.Marshal('UTF8Type');
    return utf8Serializer.serialize(JSON.stringify(data)).toString("hex");
}

想法是您可以将评论 json 对象传递给此方法,并将其推送到 cassandra。我这样称呼它来测试:

var comments = require('./comments.js');

comments.addComment("myslug",{id:2,name:"Alex",comment:"Hello!"},function(e,r){
    console.log(e);
    console.log(r);
})

但每当我这样做(我尝试了各种 CQL 驱动程序)时,我都会收到这个神秘的错误消息:

[HelenusInvalidRequestException: unable to coerce 'value' to a  formatted date (long)] name: 'HelenusInvalidRequestException'

我尝试将时间戳更改为所有不同的数据类型,但没有运气。非常奇怪的是,起初,我的主键只是 slug 本身,然后它确实起作用了。但是,我想将所有注释存储在按时间戳排序的一行中,因此我不得不采用这种使用两列作为主键的方法。有任何想法吗?

编辑所以根据rs_atl 的建议,这是我尝试过的:

这一行:

dateSerializer.serialize(date).toString('hex')

实际上确实返回了垃圾(0000013ccfacf5c4),我一定误解了如何使用API​​。所以这就是我尝试的方法:

我尝试new Date().getTime()了 JS 中的 which 实际上返回了 Unix 风格的纪元,但这没有用,我得到了同样的错误。然后我尝试使用moment.js来尝试格式化字符串:

moment().format("YYYY-MM-DD HH:mm:ss")

这似乎返回了正确的格式,但又一次。同样的错误。然后我尝试了这个:

moment().format("YYYY-MM-DD HH:mm") + "Z"

没运气。然后我尝试了这个:

moment().format("YYYY-MM-DD HH:mmZ")

实际上,它确实在最后添加了时区信息,但仍然没有运气。有任何想法吗?

4

3 回答 3

1

我不确定这条线的输出是什么:

return dateSerializer.serialize(date).toString('hex');

但这就是您的问题所在。您似乎没有输出 Cassandra 理解的有效日期。有效日期是:

  1. 一个 Unix 风格的 epoch 作为 long 值。

  2. 以下形式之一的字符串:

    yyyy-mm-dd HH:mm
    yyyy-mm-dd HH:mm:ss
    yyyy-mm-dd HH:mmZ
    yyyy-mm-dd HH:mm:ssZ
    yyyy-mm-dd'T'HH:mm
    yyyy-mm -dd'T'HH:mmZ
    yyyy-mm-dd'T'HH:mm:ss
    yyyy-mm-dd'T'HH:mm:ssZ
    yyyy-mm-dd
    yyyy-mm-ddZ

检查以确保您正在编写这些有效的时间戳类型之一。

于 2013-02-11T14:11:24.513 回答
1

看来您使用了错误的 CQL 版本。您希望使用 CQL 3.0.0,但驱动程序默认为 CQL2。您需要在初始化时指定正确的 CQL 版本。

pool = new helenus.ConnectionPool({
    hosts: ['localhost:9160'],
    keyspace: 'blogks',
    cqlVersion: '3.0.0'
});

此外,请确保您使用的是 Helenus 的最新版本(截至目前为 0.6.2)。

于 2013-02-12T21:23:23.197 回答
0

对于时间戳,我一直使用 int 以毫秒为单位来表示时间。

尝试:

Date.now()

代替:

serializeDate(new Date())
于 2013-03-20T16:51:22.190 回答