2017-06-05 33 views
0

我使用这个驱动程序卡桑德拉badgateway:https://github.com/datastax/php-driver卡桑德拉PHP驱动器502从准备好的声明

这是我用来创建表的代码:

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); 

,这里是我的PHP代码片段导致502网关:

$session = $cluster->connect($keyspace); 
$selectstmt = $session->prepare("SELECT suserid, susername, snickname, msg, savatar, timestamp FROM packages_by_userid WHERE ruserid IN (?, ?) AND suserid IN (?, ?) AND timestamp < ? LIMIT 40;"); 
$params = array('ruserid' => array($rid, $sid), 'suserid' => array($rid, $sid), 'timestamp' => $endtimestamp); 
$options = array('arguments' => $params); 
$future = $session->executeAsync($selectstmt, $options); 
$result = $future->get(); 

我相信我搞砸了将参数绑定到准备好的语句。在我的情况下,这样做的正确方法是什么,因为我必须将多个值绑定到ruseridsuserid

感谢任何人都可以提供帮助。

+0

在我看来,* ruserid IN(?,?)AND suserid IN(?,?)*不是有效的CQL语法。 – xmas79

+0

它工作正常,如果我不使用准备好的语句,也在命令行 –

+0

我想我理解你的用例,你正试图从两个用户之间获得packageuuid。戒指?并使用当前的时间戳packageuuid生成? –

回答

1

我建议你改变你的数据模型如下图所示:

CREATE TABLE packages (
    cnvid text, 
    packageuuid timeuuid, 
    ruserid text, 
    suserid text, 
    PRIMARY KEY (cnvid, packageuuid) 
); 

这里cnvid是对话ID。您可以使用以下功能创建对话ID:

function makeConversationId($ruserid, $suserid) { 
    return $ruserid <= $suserid ? $ruserid . ':' . $suserid : $suserid . ':' . $ruserid ; 
} 

无论发送者还是接收者您的对话ID都是相同的。即

echo makeConversationId('1', '2') . '<br/>'; 
echo makeConversationId('2', '1'); 

输出:

1:2 
1:2 

现在你有cnvid,只要你insert/update/delete/select用上面的方法做cnvid。

虽然packageuuid是timeuuid,但您的所有packageuuid将按时间排序。

所以查询首先创建cnvid(即1:2),然后创建您要查询(即896f8110-49d4-11e7-ade6-493d3332b999

检查与时间戳timeuuid这样的:https://datastax.github.io/php-driver/api/Cassandra/class.Timeuuid/

所以,你可以查询得到

实施例的数据:

cnvid | packageuuid       | ruserid | suserid 
-------+--------------------------------------+---------+--------- 
    3:4 | bc0809e0-49d3-11e7-ade6-493d3332b999 |  3 |  4 
    1:2 | 1f4aae70-49d1-11e7-ade6-493d3332b999 |  1 |  2 
    1:2 | 237ff3b0-49d1-11e7-ade6-493d3332b999 |  2 |  1 
和2,其时间戳记大于给定的时间戳之间更大的用户包

查询:

SELECT * FROM packages WHERE cnvid = '1:2' AND packageuuid < 896f8110-49d4-11e7-ade6-493d3332b999; 

输出:

cnvid | packageuuid       | ruserid | suserid 
-------+--------------------------------------+---------+--------- 
    1:2 | 1f4aae70-49d1-11e7-ade6-493d3332b999 |  1 |  2 
    1:2 | 237ff3b0-49d1-11e7-ade6-493d3332b999 |  2 |  1 

所以你不需要物化视图和查询。

+0

顺便说一下,它可以与PHP驱动程序不同。我用它与Datastax Java驱动程序 –

+0

这不适用于我,我是否应该更改$ params行? –

+0

我得到错误:'致命错误:未被捕获的Cassandra \ Exception \ InvalidArgumentException:没有值或名称列' –