Cassandra-CQL查询[COUNT,ORDER_BY,GROUP_BY]

时间:2018-12-02 17:56:35

标签: cassandra group-by cql

我是Cassandra的新手,我想进一步了解该数据库引擎的工作方式(特别是CQL部分),并将其与Mysql进行比较。

考虑到这一点,我尝试了一些查询,但是有一个我无法弄清楚的特定查询。 从我的阅读中可以看出,不可能在Cassandra中执行此查询,但是我想确定是否可以解决此问题。

想象一下带有PRIMARY_KEY = id的下表[Customer]:

id, name, city, country, email 
01, Jhon, NY, USA, jhon@
02, Mary, DC, USA, mary@
03, Smith, L, UK, smith@
.....

我想获得一个列表,该列表显示我每个国家和按订单排序的客户数。

在mySQL中,它将类似于

SELECT COUNT(Id), country 
FROM customer
GROUP BY country
ORDER BY COUNT(Id) DESC

但是在Cassandra(CQL)中,看来我无法对非PRIMARY_KEY的列进行GROUP BY(例如“ country”的情况),无论如何都存在这个问题?

2 个答案:

答案 0 :(得分:0)

您需要在“国家/地区”上定义二级索引。二级索引用于查询使用通常不是查询表的列的表。

对于ORDER BY,您需要在'id'上定义聚簇键。聚簇键负责对分区中的数据进行排序。

答案 1 :(得分:0)

在Cassandra中构建表时,要记住的主要事情是根据计划查询的方式对它的PRIMARY KEY建模。无论如何,将id定义为PRIMARY KEY对您要执行的操作不是很有帮助。

此外,诸如GROUP BYORDER BY之类的关键字有特殊要求。除非您计划反转排序方向,否则ORDER BY特别是毫无用处(IMO)。但是您不能选择任意列来对数据进行排序。

要解决上述查询,我​​将创建一个新表,该表以countrycityid列(按此顺序)为键:

CREATE TABLE customer_by_city (
  id TEXT,
  name TEXT,
  city TEXT,
  country TEXT,
  email TEXT,
  PRIMARY KEY (country,city,id)
) WITH CLUSTERING ORDER BY (city ASC, id DESC);

现在,我将插入行:

INSERT INTO customer_by_city (id,name,city,country,email)
     VALUES ('01', 'Jhon', 'NY', 'USA', 'jhon@gmail.com');
INSERT INTO customer_by_city (id,name,city,country,email)
     VALUES ('02', 'Mary', 'DC', 'USA', 'mary@gmail.com');
INSERT INTO customer_by_city (id,name,city,country,email)
     VALUES ('03', 'Smith', 'London', 'UK', 'smith@gmail.com');

SELECT COUNT(Id), country  FROM customer_by_city  GROUP BY country ;

 system.count(id) | country
------------------+---------
                2 |     USA
                1 |      UK

(2 rows)

Warnings :
Aggregation query used without partition key

注意:

  • 最后一条消息表示您正在运行查询,而没有由分区键键入的WHERE子句。这意味着Cassandra将必须检查集群中的每个节点才能提供此查询。 高度效率低下。
  • 虽然在本示例中有效,但是country作为分区键可能不是分发数据的最佳方法。毕竟,如果大多数客户都在一个特定的国家/地区,那么他们就有可能突破最大分区大小的界限。