在Cassandra使用CQL宽行 – 得到奇怪的错误

我试图在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。 我叫它这样testing:

 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' 

我试图改变时间戳是所有不同的数据types,但没有运气。 非常奇怪的是,起初,我的主要关键只是自己的slu and,然后才起作用。 但是,我想将所有注释按时间顺序存储在一行中,因此我必须采用这种使用两列主键的方法。 有任何想法吗?

编辑所以基于rs_atl的build议,这是我已经尝试:

这一行:

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

其实回报垃圾(0000013ccfacf5c4),我一定误解了如何使用API​​。 所以这就是我所尝试的:

我试图只是new Date().getTime()在JS确实返回Unix风格的纪元,但没有工作,我得到了同样的错误。 然后我尝试使用moment.js尝试格式化string:

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

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

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

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

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

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

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

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

也请确保您使用的是Helenus的最新版本(现在是0.6.2)。

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

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

但这是你的问题所在。 看来你并没有输出Cassandra能够理解的有效date。 有效的date是:

  1. 一个Unix风格的时代作为一个长期的价值。

  2. 以下列forms之一的string:

    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:毫米
    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

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

对于时间戳,我总是用毫秒来表示时间。

尝试:

 Date.now() 

代替:

 serializeDate(new Date())