但是是否可以查询:select id, cities from user where cities contains {name:'My City'};
不,不是。 using a UDT 上的文档状态(对于 UDT 列 name):
- 在用户定义类型的列上过滤数据。创建索引,然后运行条件查询。在 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 反模式,所以我会谨慎使用它。这一切都取决于您的应用程序的需求,以及您是想将大部分时间花在数据建模/管理上还是在客户端进行处理。老实说,我更喜欢让客户端尽可能简单。