首页 文章

如何通过用户定义类型的字段过滤cassandra查询

提问于
浏览
4

如何按用户定义的类型字段过滤cassandra查询?我想在我的cassandra数据库中创建人员表,所以我在我的cassandra数据库中创建这个用户定义的类型 .

create type fullname ( firstname text, lastname text );

我也有这张 table .

create table people ( id UUID primary key, name frozen <fullname> );

我需要过滤我的查询,以了解姓jolie的所有人 . 我该如何从这个表中查询 . 以及如何在cassandra中过滤和查询?我知道我可以删除fullname类型并将firstname和lastname添加到主表,但它是我想要做的样本 . 我必须有fullname类型 .

1 回答

  • 5

    简短回答:您可以使用二级索引按全名UDT进行查询 . 但是你不能仅通过UDT的一部分进行查询 .

    // create table, type and index
    create type fullname ( firstname text, lastname text );
    create table people ( id UUID primary key, name frozen <fullname> );
    create index fname_index on your_keyspace.people (name);
    
    // insert some data into it
    insert into people (id, name) values (now(), {firstname: 'foo', lastname: 'bar'});
    insert into people (id, name) values (now(), {firstname: 'baz', lastname: 'qux'});
    
    // query it by fullname
    select * from people where name = { firstname: 'baz', lastname: 'qux' };
    
    // the following will NOT work:
    select * from people where name = { firstname: 'baz'};
    

    这种行为的原因是实现C *二级索引的方式 . 一般来说,它只是由C *维护的另一个隐藏表,在您的情况下定义为:

    create table fname_index (name frozen <fullname> primary key, id uuid);
    

    实际上,您的辅助键和主键在此表中交换 . 所以你的案例被简化为一个更普遍的问题'为什么我不能只通过PK的一部分查询?':

    • 整个PK值(firstname lastname)经过哈希处理,结果数字定义了存储行的分区 .

    • 对于该分区,您的行将附加到memtable(后来在磁盘上刷新到SSTable,一个按键排序的文件)

    • 当你只想通过PK的一部分进行查询时(比如仅使用firstname),C *不能计算整个fullname的hashcode,因为lastname是未知的),因为你的匹配可以在任何需要完整的分区中的任何地方 . 表扫描 . C *明确禁止这些扫描,所以你别无选择:)

    建议的解决方案:

    • 将UDT拆分为firstname和lastname等基本部分,并在其上设置二级索引 .

    • 使用具有物化视图功能的Cassandra 3.0(实际上强制cassandra维护部分UDT的自定义索引)

    • 重新审视您的数据模型不那么严格(当没有人强迫您使用UDT时,他们没有帮助)

相关问题