我正在尝试为Cassandra中的博客存储评论,并提出了这种模式(从here获得了想法):
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's建议,这是我尝试过的:
这一行:
dateSerializer.serialize(date).toString('hex')
实际上确实返回垃圾(0000013ccfacf5c4),我一定误解了如何使用API。所以这就是我试过的:
我试过new Date().getTime()
这实际上在JS中确实返回了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")
实际上确实在最后添加了时区信息,但仍然没有运气。有什么想法吗?
答案 0 :(得分:1)
我不确定这一行的输出是什么:
return dateSerializer.serialize(date).toString('hex');
但这就是您的问题所在。您似乎没有输出Cassandra理解的有效日期。有效日期为:
Unix风格的时代作为长值。
以下表格之一的字符串:
检查以确保您正在编写其中一种有效的时间戳类型。
答案 1 :(得分: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)。
答案 2 :(得分:0)
对于时间戳,我总是用毫秒来表示时间。
尝试:
Date.now()
而不是:
serializeDate(new Date())