cassandra中的嵌套查询

时间:2017-10-12 02:39:14

标签: java cassandra cql cql3 cqlsh

我是cassandra的新手,我试图向员工插入笔记本电脑映射列表,如下所示' laptoplist'是一个UDT。

   cqlsh:sourceutilization> SELECT * from employee ;

 id | laptoplist                                                                        | name      | type
----+-----------------------------------------------------------------------------------+-----------+------------
  5 |  [{laptopid: 5, cpu: 9, memory: 18, networkutilization: 25, diskutilization: 85}] | testname5 | staffType5
  1 | [{laptopid: 1, cpu: 94, memory: 36, networkutilization: 13, diskutilization: 66}] | testname1 | staffType1
  8 |  [{laptopid: 8, cpu: 64, memory: 1, networkutilization: 15, diskutilization: 71}] | testname8 | staffType8
  0 |  [{laptopid: 0, cpu: 4, memory: 95, networkutilization: 20, diskutilization: 16}] | testname0 | staffType0
  2 | [{laptopid: 2, cpu: 49, memory: 37, networkutilization: 20, diskutilization: 88}] | testname2 | staffType2
  4 | [{laptopid: 4, cpu: 13, memory: 67, networkutilization: 67, diskutilization: 10}] | testname4 | staffType4
  7 | [{laptopid: 7, cpu: 11, memory: 75, networkutilization: 75, diskutilization: 97}] | testname7 | staffType7
  6 |  [{laptopid: 6, cpu: 27, memory: 34, networkutilization: 2, diskutilization: 92}] | testname6 | staffType6
  9 | [{laptopid: 9, cpu: 12, memory: 10, networkutilization: 19, diskutilization: 73}] | testname9 | staffType9
  3 | [{laptopid: 3, cpu: 47, memory: 13, networkutilization: 72, diskutilization: 54}] | testname3 | staffType3

现在,我想查询下面的内容,如何实现

select * from employee where laptoplist.networkutilization > 50;

仅供参考,我使用的是3.1 cassandra版本。

提前致谢, 哈利

2 个答案:

答案 0 :(得分:2)

这样做不会很好。在这里获得您想要的东西需要进行一些更改。在Cassandra,有两件事情通常会有所帮助。

  1. 如果您在使用数据模型时遇到问题,请问问自己,这可能是一个时间序列。
  2. 使用Cassandra的分布式附加存储引擎,时间序列和事件跟踪等用例很容易适应。有时候,当调整到那个角度时,数据模型更有意义(从Cassandra的角度来看)。

    1. 构建表以匹配您的查询模式。
    2. 我看到ID可能是主要的关键。但我没有看到(至少在上面)是过滤ID的任何查询。我可以说像员工和笔记本电脑这样的东西很重要,而且可能是独一无二的。但是,唯一键并不总能成为最佳信息过滤器。

      要问的主要问题是,你想要到达什么地方?

      对我来说,您希望看到正在经历高网络利用率的用户。高网络利用率是(希望)暂时的事情,那么为什么我们不向它添加时间组件(checkpoint_time)? IMO,随着时间的推移跟踪计算资源利用率是有意义的。在考虑了这些要点之后,我想出了这样一个数据模型:

      cassdba@cqlsh:stackoverflow> CREATE TABLE employee_laptop__by_network_utilization (
                             timebucket text,
                             checkpoint_time timestamp,
                             employee_id bigint,
                             name text,
                             type text,
                             laptop_id bigint,
                             cpu bigint,
                             memory bigint,
                             network_utilization bigint,
                             disk_utilization bigint,
                             PRIMARY KEY ((timebucket),network_utilization,
                                 checkpoint_time,employee_id,laptop_id)
                           ) WITH CLUSTERING ORDER by 
                                (network_utilization ASC, checkpoint_time DESC,
                                 employee_id ASC, laptop_id ASC);
      

      插入一些行后,我现在可以查询遇到网络利用率的员工/笔记本电脑组合> 2017年10月12日50日。

      cassdba@cqlsh:stackoverflow> SELECT * FROm employee_laptop__by_network_utilization
           WHERE timebucket='20171012' AND network_utilization > 50;
      
       timebucket | network_utilization | checkpoint_time                 | employee_id | laptop_id | cpu | disk_utilization | memory | name     | type
      ------------+---------------------+---------------------------------+-------------+-----------+-----+------------------+--------+----------+-----------
         20171012 |                  55 | 2017-10-12 12:30:00.000000+0000 |           1 |         1 |   4 |               62 |     19 | Jebediah |     Pilot
         20171012 |                  55 | 2017-10-12 12:15:00.000000+0000 |           1 |         1 |  19 |               62 |     18 | Jebediah |     Pilot
         20171012 |                  72 | 2017-10-12 12:00:00.000000+0000 |           3 |         3 |  47 |               54 |     13 |      Bob | Scientist
      
      (3 rows)
      

      首先,我需要一个好的分区密钥,两者对查询有意义,阻止我的分区无限制增长。因此,我选择了一个名为“日期存储桶”的timebucket。这样,我可以隔离一天的查询,并确保每个查询都由单个节点提供。

      接下来,我聚集在network_utilization上,因为这是该模型主要关注的主要列。它是第一个聚类列,因为我们不希望在查询中过滤列的过多提供。

      checkpoint_time是PRIMARY KEY中的下一列,主要是因为具有相同timebucketnetwork_utilization的请求可能更有意义地按时间排序(DESCending)。

      最后,我添加employee_id表示唯一性,然后laptop_id,因为员工可以拥有多台笔记本电脑。

      现在,我确信您将找到与您的用例不完全相符的解决方案。这是因为Cassandra数据建模非常以用例为中心。通常,一个好的解决方案不是适合另一个人。但是,这是获取您所追求的数据的一种方式。

答案 1 :(得分:0)

您不能只对任何列进行范围查询。 cassandra有一些限制。

在cassandra上创建任何架构之前,您必须具体说明要以何种方式执行查询,否则大部分时间您的架构将无效。

要执行大于,大于等于,小于,小于等于的范围查询,您需要在模式中指定群集列。

我们不能简单地在cassandra中仅指定Clustering列。您必须在cassandra的每个模式中声明分区键。

要对群集列执行查询,您必须在查询中传递所有先前的主键值。