在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是:
-
一个Unix风格的时代作为一个长期的价值。
-
以下列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())