我是Cassandra的新手,我需要它来做一个快速而小巧的工作。 但是,我遇到了问题。我创建了一个列族 使用下面的CQL:
CREATE TABLE dummy_file_test ( dtPtn INT, pxID INT, startTm INT, endTm INT, patID BIGINT, efile BLOB, PRIMARY KEY(dtPtn, pxID, startTm) );
我编写了以下方法将数据插入表中。
public static void insertDataKey(HashMap nameValuePair, String colFamily) {
try {
Cluster cluster = HFactory.getOrCreateCluster(clusterName, hostPort);
Keyspace keyspace = HFactory.createKeyspace(CASSANDRA_DUMMY_KEY_SPACE, cluster);
Integer dtPtn = (Integer)nameValuePair.get("dtPtn");
Integer pxID = (Integer)nameValuePair.get("pxID");
Integer startTm = (Integer)nameValuePair.get("startTm");
Integer endTm = (Integer)nameValuePair.get("endTm");
Long patID = (Long)nameValuePair.get("patID");
byte[] efile = (byte[])nameValuePair.get("efile");
HColumn<String, Integer> column1 = HFactory.createColumn("dtPtn", dtPtn, new StringSerializer(), IntegerSerializer.get());
HColumn<String, Integer> column2 = HFactory.createColumn("pxID", pxID, new StringSerializer(), IntegerSerializer.get());
HColumn<String, Integer> column3 = HFactory.createColumn("startTm", startTm, new StringSerializer(), IntegerSerializer.get());
HColumn<String, Integer> column4 = HFactory.createColumn("endTm", endTm, new StringSerializer(), IntegerSerializer.get());
HColumn<String, Long> column5 = HFactory.createColumn("patID", patID, new StringSerializer(), LongSerializer.get());
HColumn<String, byte[]> column6 = HFactory.createColumn("efile", efile, new StringSerializer(), BytesArraySerializer.get());
Composite rowKey = new Composite();
rowKey.addComponent("dtPtn", StringSerializer.get());
rowKey.addComponent(dtPtn, IntegerSerializer.get());
rowKey.addComponent("pxID", StringSerializer.get());
rowKey.addComponent(pxID, IntegerSerializer.get());
rowKey.addComponent("startTm", StringSerializer.get());
rowKey.addComponent(startTm, IntegerSerializer.get());
Mutator<Composite> mutator = HFactory.createMutator(keyspace, CompositeSerializer.get());
mutator.addInsertion(rowKey, colFamily, column1);
mutator.addInsertion(rowKey, colFamily, column2);
mutator.addInsertion(rowKey, colFamily, column3);
mutator.addInsertion(rowKey, colFamily, column4);
mutator.addInsertion(rowKey, colFamily, column5);
mutator.addInsertion(rowKey, colFamily, column6);
mutator.execute();
} catch (Exception ex) {
ex.printStackTrace();
}
}
然而,当我运行代码时,我得到了
InvalidRequestException(why:期望4或0字节int(21))
我对Hector API很困惑,找不到任何我完全可以依赖的完整教程/材料。解决上述问题的任何建议都会有很大的帮助。
提前致谢。
ps:我在Cassandra 1.2
答案 0 :(得分:4)
如果您在CQL中创建模式,那么通过CQL访问数据可能会更好。但你仍然可以通过thrift接口访问它。
在您指定的CQL中使用复合主键时,第一个键是成为行键的分区键。其他键是列组合的一部分。
所以对于你的例子,如果你做了
insert into dummy_file_test (dtPtn, pxID, startTm, endTm, patID, efile) values (1, 2, 3, 4, 5, 0x06);
然后在cassandra-cli中列出:
[default@ks] list dummy_file_test;
RowKey: 1
=> (column=2:3:, value=, timestamp=1366620262555000)
=> (column=2:3:efile, value=06, timestamp=1366620262555000)
=> (column=2:3:endtm, value=00000004, timestamp=1366620262555000)
=> (column=2:3:patid, value=0000000000000005, timestamp=1366620262555000)
你看到行键只是对应于dtPtn的整数1。主键中的其他列已添加到列名称前面。
如果要使用Hector插入此行,则需要使用dtPtn作为行键,然后使用pxID的复合列键:startTm:col_name作为列。
您还可以告诉Cassandra使您的分区键成为列的组合。为此,您需要在主键子句中使用额外的括号:
CREATE TABLE dummy_file_test
(
dtPtn INT,
pxID INT,
startTm INT,
endTm INT,
patID BIGINT,
efile BLOB,
PRIMARY KEY((dtPtn, pxID, startTm))
);
现在你的行键是dtPtn,pxID,startTm:
的组合[default@ks] list dummy_file_test;
RowKey: 1:2:3
=> (column=, value=, timestamp=1366620916952000)
=> (column=efile, value=06, timestamp=1366620916952000)
=> (column=endtm, value=00000004, timestamp=1366620916952000)
=> (column=patid, value=0000000000000005, timestamp=1366620916952000)
请注意,列名称不会出现在行键复合中,因此您无需添加它们。您的代码应该只是:
Composite rowKey = new Composite();
rowKey.addComponent(dtPtn, IntegerSerializer.get());
rowKey.addComponent(pxID, IntegerSerializer.get());
rowKey.addComponent(startTm, IntegerSerializer.get());