【问题标题】:Querying with "contains" on a list of user defined type (UDT)在用户定义类型 (UDT) 列表中使用“包含”进行查询
【发布时间】:2015-03-12 14:37:15
【问题描述】:

对于像这样的数据模型:

create type city (
   name text,
   code int
);

create table user (
    id uuid,
    name text,
    cities list<FROZEN<city>>,
    primary key ( id )
);

create index user_city_index on user(cities);

查询为

select id, cities from user where cities contains {name:'My City', code: 10};

工作正常。但是可以查询吗

select id, cities from user where cities contains {name:'My City'};

并丢弃code 属性,即code=&lt;any&gt;?

这可以通过使用 Spark 来实现吗?

【问题讨论】:

    标签: apache-spark cassandra nosql


    【解决方案1】:

    但是是否可以查询:select id, cities from user where cities contains {name:'My City'};

    不,不是。 using a UDT 上的文档状态(对于 UDT 列 name):

    1. 在用户定义类型的列上过滤数据。创建索引,然后运行条件查询。在 Cassandra 2.1.x 中,您需要在WHERE 子句中列出name 列的所有组件

    因此查询您的cities UDT 集合将需要city 类型的所有组件。

    我确信有办法在 Spark 中查询这个,但我会给你一个基于 Cassandra 的答案。基本上,创建一个额外的列表列定义/索引只是为了保存城市名称列表,然后在上面运行你的CONTAINS。更好的是,将city 类型非规范化为具有主键定义的查询表(usersbycity),例如PRIMARY KEY(cityname, citycode, userid),并在user 表之外使用它来支持按城市名称和代码进行查询(或只是城市名称)。

    请记住,Cassandra 在专门设计适合您的查询模式的表时效果最佳。二级索引是为了方便,而不是性能。尝试扩充一个表以支持多个查询是一种 RDBM 数据建模方法(通常在 Cassandra 中效果不佳)。而不是一张表很好地服务于一个查询,您通常最终会得到一张不能很好地服务于多个查询的表。

    编辑您的问题:

    1) “是否可以接受长聚类键?”

    目前我无法找到关于此的明确声明,但我认为这里更大的问题是集群密钥如何“在后台”存储/使用。本质上,每个聚类键值都附加到每个列值(以便更快地检索)。显然,如果你有很多,那会占用磁盘空间(这些天不是太大的问题......如果是这样,你可以使用 COMPACT STORAGE 指令来解决这个问题)。

    如果你有很多,它最终可能会影响性能。我可以仔细检查一下,然后回复你。我不会使用...比如说...100 个聚类键。但我不认为10有什么大不了的。我知道我已经使用 7 或 8 创建了模型,并且它们的性能很好。

    2) “如果有其他与用户相关的非规范化表(如 usersbyhobby、usersbybookread 等),由于 c* 中没有 JOIN,如何将这些表中的过滤与 usersbycity 中的过滤器结合到一个查询中?”

    您不能在查询时组合它们。您可以做的是,如果您发现您的查询需要同时来自 usersbyhobby、usersbybookread 和 usersbycity 的数据;是创建一个包含所有数据的非规范化表。根据您的查询需求,您可能需要以不同的方式订购 PRIMARY KEY,在这种情况下,您需要创建与要服务的特定查询一样多的表。

    另一种选择是进行单独的查询并在客户端管理它们。客户端 JOIN 被认为是 Cassandra 反模式,所以我会谨慎使用它。这一切都取决于您的应用程序的需求,以及您是想将大部分时间花在数据建模/管理上还是在客户端进行处理。老实说,我更喜欢让客户端尽可能简单。

    【讨论】:

    • 感谢您的回答。也许它需要另一个问答条目,无论如何这里有几个问题:1)是否可以接受长聚类键,例如city有10个字段要过滤,那么可以将所有这10个字段放入主聚类键键入usersbycity? 2) 如果有其他与user 相关的非规范化表(如usersbyhobbyusersbybookread 等),我如何将这些表中的过滤与usersbycity 中的过滤结合到一个查询中,因为其中没有JOIN c*?
    猜你喜欢
    • 2016-03-21
    • 2018-08-18
    • 2010-10-21
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    • 2020-02-29
    • 2012-05-10
    相关资源
    最近更新 更多