如何按用户定义类型的字段过滤 cassandra 查询 [英] how to filter cassandra query by a field in user defined type

查看:21
本文介绍了如何按用户定义类型的字段过滤 cassandra 查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何按用户定义的类型字段过滤 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 查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆