Triggers 如何在触发器中填充不同Cassandra表的突变

Triggers 如何在触发器中填充不同Cassandra表的突变,triggers,cassandra,row,mutation,Triggers,Cassandra,Row,Mutation,我正在尝试实现一个Cassandra触发器,这样当keyspace1.tableA上有更新或删除时,触发器将向keyspace1.tableB添加一行 表B中列的名称与表A中列的名称完全不同 我正在使用Cassandra 2.1,没有选择移动到更新的版本。查看InvertedIndex触发器示例,我可以看到添加突变的基础知识: 从InvertedIndex示例中: for (Cell cell : update) { // Skip the row marker

我正在尝试实现一个Cassandra触发器,这样当keyspace1.tableA上有更新或删除时,触发器将向keyspace1.tableB添加一行

表B中列的名称与表A中列的名称完全不同

我正在使用Cassandra 2.1,没有选择移动到更新的版本。查看InvertedIndex触发器示例,我可以看到添加突变的基础知识:

从InvertedIndex示例中:

    for (Cell cell : update)
    {
        // Skip the row marker and other empty values, since they lead to an empty key.
        if (cell.value().remaining() > 0)
        {
            Mutation mutation = new Mutation(properties.getProperty("keyspace"), cell.value());
            mutation.add(properties.getProperty("columnfamily"), cell.name(), key, System.currentTimeMillis());
            mutations.add(mutation);
        }
    }
挑战在于,在本例中,传递给mutation.add的单元格名称是cell.name(),这是一个现有对象,我们可以使用该函数获取其名称

现在,我只是想存储对tableA进行更改的时间,因此tableB有两列:

  • 更改时间时间UUID
  • 操作文本
我需要添加一个突变,它将在表B中添加一行,并执行changetime和操作。如何在Cassandra 2.1.12中添加这样的行突变

我已尝试此操作,但触发器中出现空指针异常:

...
String keycol = "changetime";
ByteBuffer uuidKey = ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes()); 
ColumnIdentifier ci = new ColumnIdentifier(keycol, false);
CellName cn = CellNames.simpleSparse(ci);
mutation = new Mutation(keyspace, uuidKey);
mutation.add(tableName,cn, uuidKey, System.currentTimeMillis());
...

任何帮助都将不胜感激-我不了解Cassandra的内部结构,因此任何细节都不是太多的信息。

答案是使用CFMetaData comparator创建突变所需的细胞名。添加(…)。为了提供一个具体的示例,我将使用Cassandra 3.0 AuditTrigger中的模式和示例,可在

在这种情况下,我们将要写入的表是定义如下的test.audit表:

CREATE TABLE test.audit (key timeuuid, keyspace_name text,
    table_name text, primary_key text, PRIMARY KEY(key));
此表有一个名为“key”的分区键,没有集群列。有关定义,请参阅“分区键和集群列”一节

这一点很重要,因为对makeCellName的调用(我们将在下面的示例代码中看到)采用了一个变量列表,其中每个参数都是我们希望相应的集群列对将受影响的行采用的值,最后一个参数是文本格式的列名称

如果没有集群列(如本模式中的情况),那么对makeCellName的调用只接受一个参数:列的名称

综上所述,Cassandra 2.1的AuditTrigger函数与3.0示例的功能相同,如下所示:

public Collection<Mutation> augment(ByteBuffer key, ColumnFamily update)
{
    CFMetaData cfm = update.metadata();

    List<Mutation> mutations = new ArrayList<>(update.getColumnCount());

    String keyspaceName = "";
    String tableName    = "";
    String keyStr       = "";

    keyspaceName = cfm.ksName;
    tableName = cfm.cfName;

    try {
        keyStr = ByteBufferUtil.string(key);
    } catch (CharacterCodingException e) {
        StringWriter errors = new StringWriter();
        e.printStackTrace(new PrintWriter(errors));
        logger.error(errors.toString());
    }

    for (Cell cell : update)
    {
        // Skip the row marker and other empty values, since they lead to an empty key.
        if (cell.value().remaining() > 0)
        {
            CFMetaData other = Schema.instance.getCFMetaData("test","audit");
            CellNameType cnt = other.comparator;

            ByteBuffer auditkey = UUIDType.instance.decompose(UUIDGen.getTimeUUID());

            // create CellName objects for each of the columns in the audit table row we are inserting
            CellName primaryKeyCellName = cnt.makeCellName("primary_key");
            CellName keyspaceCellName = cnt.makeCellName("keyspace_name");
            CellName tableCellName = cnt.makeCellName("table_name");

            try {
                // put the values we want to write to the audit table into ByteBuffer objects
                ByteBuffer ksvalbb,tablevalbb,keyvalbb;
                ksvalbb=ByteBuffer.wrap(keyspaceName.getBytes("UTF8"));
                tablevalbb=ByteBuffer.wrap(tableName.getBytes("UTF8"));
                keyvalbb=ByteBuffer.wrap(keyStr.getBytes("UTF8"));

                // create the mutation object
                Mutation mutation = new Mutation(keyspaceName, auditkey);

                // get the time which will be needed for the call to mutation.add
                long mutationTime=System.currentTimeMillis();

                // add each of the column values to the mutation
                mutation.add("audit", primaryKeyCellName, keyvalbb,  mutationTime);
                mutation.add("audit", keyspaceCellName,  ksvalbb,  mutationTime);
                mutation.add("audit", tableCellName, tablevalbb,  mutationTime);

                mutations.add(mutation);
            } catch (UnsupportedEncodingException e) {
                StringWriter errors = new StringWriter();
                e.printStackTrace(new PrintWriter(errors));
                logger.error(errors.toString());
            }
        }
    }
    return mutations;
} 
公共集合扩充(ByteBuffer键,ColumnFamily更新)
{
CFMetaData cfm=update.metadata();
列表变量=新的ArrayList(update.getColumnCount());
字符串keyspaceName=“”;
字符串tableName=“”;
字符串keyStr=“”;
keyspaceName=cfm.ksName;
tableName=cfm.cfName;
试一试{
keyStr=ByteBufferUtil.string(key);
}捕获(字符编码异常e){
StringWriter错误=新建StringWriter();
e、 printStackTrace(新的PrintWriter(错误));
logger.error(errors.toString());
}
用于(单元格:更新)
{
//跳过行标记和其他空值,因为它们会导致一个空键。
if(cell.value().remaining()>0)
{
CFMetaData other=Schema.instance.getCFMetaData(“测试”、“审核”);
CellNameType cnt=其他。比较器;
ByteBuffer auditkey=UUIDType.instance.decompose(UUIDGen.getTimeUUID());
//为要插入的审核表行中的每一列创建CellName对象
CellName primaryKeyCellName=cnt.makeCellName(“主键”);
CellName keyspaceCellName=cnt.makeCellName(“keyspace_name”);
CellName tableCellName=cnt.makeCellName(“表格名称”);
试一试{
//将要写入审核表的值放入ByteBuffer对象中
ByteBuffer ksvalbb、tablevalbb、keyvalbb;
ksvalbb=ByteBuffer.wrap(keyspaceName.getBytes(“UTF8”);
tablevalbb=ByteBuffer.wrap(tableName.getBytes(“UTF8”);
keyvalbb=ByteBuffer.wrap(keyStr.getBytes(“UTF8”);
//创建变异对象
突变=新突变(keyspaceName,auditkey);
//获取调用mutation.add所需的时间
long mutationTime=System.currentTimeMillis();
//将每个列值添加到变量
添加(“审计”,primaryKeyCellName,keyvalbb,mutationTime);
添加(“审计”,keyspaceCellName,ksvalbb,mutationTime);
添加(“审计”,tableCellName,tablevalbb,mutationTime);
突变。添加(突变);
}捕获(不支持的编码异常e){
StringWriter错误=新建StringWriter();
e、 printStackTrace(新的PrintWriter(错误));
logger.error(errors.toString());
}
}
}
返回突变;
} 

您能否给出NPE堆栈跟踪,并指出在代码示例中发生这种情况的位置。在几位专家的帮助下,我找到了问题的根源,我在下面发布了答案,感谢您的跟进。那么包含聚集键的表呢?在这种情况下如何创建CellName?在f中我试图在触发器中插入一行以审核表,但我一直坚持为集群单元名称提供突变。