问题描述
如何按用户定义的类型字段过滤 cassandra 查询?我想在我的 cassandra 数据库中创建 people 表,所以我在我的 cassandra 数据库中创建了这个用户定义类型.
how to filter cassandra query by user defined type field?i want to create people table in my cassandra database so i create this user-defined-type in my cassandra database.
create type fullname ( firstname text, lastname text );
我也有这张桌子.
create table people ( id UUID primary key, name frozen <fullname> );
而且我需要过滤我的查询以了解所有姓氏为 jolie 的人.我如何从这个表中查询这个.以及完全如何在 cassandra 中进行过滤和查询?我知道我可以删除全名类型并将名字和姓氏添加到主表中,但它是我想要做的一个示例.我必须有全名类型.
and i need to filter my query to know all people with lastname jolie.how can i query this from this table.and totally how is filtering and query in cassandra?I know i can delete fullname type and add firstname and lastname to main table but it is a sample of what i want to do.i must have fullname type.
推荐答案
简答:可以使用二级索引按全名 UDT 查询.但是您不能仅通过 UDT 的一部分进行查询.
Short answer: you can use secondary indexes to query by fullname UDT. But you cannot query by only a part of your 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* 维护的另一个隐藏表,在您的情况下定义为:
The reason for such behaviour is a way C* secondary indexes are implemented. In general, it's just another hidden table maintained by C*, in your case defined as:
create table fname_index (name frozen <fullname> primary key, id uuid);
实际上您的辅助键和主键在此表中交换.因此,您的案例简化为更一般的问题为什么我不能仅通过 PK 的一部分进行查询?":
Actually your secondary and primary keys are swapped in this table. So your case is reduced to a more general question 'why can't I query by only a part of PK?':
- 整个 PK 值(名字 + 姓氏)都经过哈希处理,结果数字定义了用于存储您的行的分区.
- 对于那个分区,你的行被附加到一个内存表(然后在磁盘上刷新到 SSTable,一个按键排序的文件)
- 当您只想按 PK 的一部分进行查询时(例如仅按名字),C* 无法猜测要查找的分区(因为它无法将整个全名的哈希码计算为姓氏)未知),因为您的匹配项可以在任何需要全表扫描的分区中的任何位置.C* 明确禁止这些扫描,所以你别无选择 :)
建议的解决方案:
- 将您的 UDT 拆分为名字和姓氏等重要部分,并在其上设置二级索引.
- 使用具有物化视图功能的 Cassandra 3.0(实际上强制 cassandra 为部分 UDT 维护自定义索引)
- 重新审视您的数据模型,使其不那么严格(当没有人强迫您使用无用的 UDT 时)
这篇关于如何按用户定义类型的字段过滤 cassandra 查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!