2017-06-04 41 views
1

这是我用来创建表的代码:卡桑德拉CQL替代或WHERE子句

CREATE TABLE test.packages (
    packageuuid timeuuid, 
    ruserid text, 
    suserid text, 
    timestamp int, 
    PRIMARY KEY (ruserid, suserid, packageuuid, timestamp) 
); 

,然后创建一个物化视图:

CREATE MATERIALIZED VIEW test.packages_by_userid 
    AS SELECT * FROM test.packages 
    WHERE ruserid IS NOT NULL 
     AND suserid IS NOT NULL 
     AND TIMESTAMP IS NOT NULL 
     AND packageuuid IS NOT NULL 
    PRIMARY KEY (ruserid, suserid, timestamp, packageuuid) 
    WITH CLUSTERING ORDER BY (packageuuid DESC); 

我希望能够搜索对于两个ID

之间发送的数据包

,所以我需要这样的:

SELECT * FROM test.packages_by_userid WHERE (ruserid = '1' AND suserid = '2' AND suserid = '1' AND ruserid = '2') AND timestamp > 1496601553; 

我该如何用CQL完成这样的事情?

我已经搜索了一下,但我无法弄清楚。

我愿意改变表的结构,如果它会使这样的事情成为可能。

如果没有物化视图也是可行的,那也不错。

回答

1

使用IN子句:

SELECT * FROM test.packages_by_userid WHERE ruserid IN ('1', '2') AND suserid IN ('1','2') AND timestamp > 1496601553; 

注:保持在第尺寸较小,大在分区可能会导致GC暂停现象,导致性能整体较慢堆压条款

实际上,这意味着你在等待这个单一的协调器节点给你一个响应,它将所有这些查询和它们的响应保存在堆中,并且如果其中一个查询fa ils,或协调员失败,你必须重试整个事情。

如果多分区在子句中较大尝试使用单独查询,对于每个分区(ruserid)和executeAsync

SELECT * FROM test.packages_by_userid WHERE ruserid = '1' AND suserid IN ('1','2') AND timestamp > 1496601553; 
SELECT * FROM test.packages_by_userid WHERE ruserid = '2' AND suserid IN ('1','2') AND timestamp > 1496601553; 

了解更多:https://lostechies.com/ryansvihla/2014/09/22/cassandra-query-patterns-not-using-the-in-query-for-multiple-partitions/

+0

再次感谢! in子句总是包含两个用户ID,所以希望我没有减速问题。 –

+0

这很好,那么你可以毫无疑问地使用子句解决方案。 –

+0

我从来没有见过CQL语法* ruserid IN('1','2')和suserid IN('1','2')*带有双* IN *子句。其中Cassandra版本的语法是否有效?你的意思是*(ruserid,suserid)IN(('1','2'),('1','2'))*? – xmas79

0

既然你随时搜索发送者和接收者,我会用下面的表格布局模型这样的:

CREATE TABLE test.packages (
    ruserid text, 
    suserid text, 
    timestamp int, 
    packageuuid timeuuid, 
    PRIMARY KEY ((ruserid, suserid), timestamp) 
); 

这样,每对您需要运行两个查询,每个分区一个:

SELECT * FROM packages WHERE ruserid=1 AND suserid=2 AND timestamp > 1496601553; 
SELECT * FROM packages WHERE ruserid=2 AND suserid=1 AND timestamp > 1496601553; 

这是恕我直言的最佳解决方案,因为请记住,在卡桑德拉你从你的查询开始,并建立你的表模型,从来没有相反。