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'

タイムスタンプをすべて異なるデータ型に変更しようとしましたが、うまくいきませんでした。非常に奇妙なことは、最初は私の主キーがナメクジそのものでしたが、それが機能したことです。ただし、すべてのコメントをタイムスタンプ順に1行に格納したいので、主キーに2つの列を使用するというこのアプローチを採用する必要がありました。何か案は?

編集rs_atlの提案に基づいて、これが私が試したことです:

この行:

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

実際にガベージ(0000013ccfacf5c4)を返しましたが、APIの使用方法を誤解していたに違いありません。代わりにこれが私が試したものです:

JSで実際にUnixスタイルのエポックを返すものを試してみましnew Date().getTime()たが、それは機能しませんでした。同じエラーが発生しました。次に、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スタイルのエポック。

  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 に答える