【问题标题】:Cassandra PHP driver 502 badgateway from prepared statement来自准备好的语句的 Cassandra PHP 驱动程序 502 badgateway
【发布时间】:2017-11-05 21:29:15
【问题描述】:

我正在为 cassandra 使用这个驱动程序:https://github.com/datastax/php-driver

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

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 代码的 sn-p,它导致 502 bad gateway:

$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

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

【问题讨论】:

  • 在我看来 ruserid IN (?, ?) AND suserid IN (?, ?) 不是有效的 CQL 语法。
  • 如果我不使用准备好的语句并且在命令行中也可以正常工作
  • 我想我理解了您的用例,您正试图从两个用户之间获取 packageuuid。环? packageuuid 是使用当前时间戳生成的吗?
  • 是的,我正在尝试通过他们的 ID 获取两个用户之间发送的所有包的数据,并且 packageuuid 是从当前时间戳生成的。

标签: php cassandra


【解决方案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),然后创建一个带有您要查询的时间戳的timeuuid(即896f8110-49d4-11e7-ade6-493d3332b999

检查这个:https://datastax.github.io/php-driver/api/Cassandra/class.Timeuuid/

因此您可以查询以获取时间戳大于给定时间戳的 1 到 2 之间的用户包:

示例数据:

 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

查询:

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

因此您不需要物化视图和 In 查询。

【讨论】:

  • 顺便说一句,它可能与 PHP-Driver 不同。我已经将它与 Datastax Java-Driver 一起使用
  • 这对我不起作用,我是否也应该更改 $params 行?
  • 我收到错误:Fatal error: Uncaught Cassandra\Exception\InvalidArgumentException: No value or column for name
  • 再次感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2013-05-31
  • 2013-07-10
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 2015-08-13
  • 2015-06-23
  • 1970-01-01
相关资源
最近更新 更多