【问题标题】:Cassandra use aggregate function and then order by that aggregateCassandra 使用聚合函数,然后按该聚合排序
【发布时间】:2019-03-09 08:42:27
【问题描述】:

我有一个带有以下列的表的 cassandra 数据库:

  • itemid
  • 用户名
  • 评分

itemiduserid 是主键。我的查询如下所示:

SELECT itemid, avg(rating) as avgRating from mytable GROUP BY itemid order by avgRating asc;

我收到以下错误:

InvalidRequest: 来自服务器的错误:code=2200 [Invalid query] message="仅当分区键受 EQ 或 IN 限制时才支持 ORDER BY。"

我该如何解决这个问题?

我需要按照平均评分排序,这样我才能根据平均评分获得前 10 部电影。

【问题讨论】:

  • 在 Cassandra 中,您围绕查询而不是数据对表进行建模。因此,从这个角度来看,如果您的查询将根据平均评分获得前 10 部电影,您将需要一个满足该查询的表。表结构可以非常简单,比如电影 id 和评分,电影 id 作为主键,评分作为聚类列有序 desc。缺点是您需要维护该表(例如定期更新平均评分)。
  • @Horia 一个简单的电影 id 和评级表并不能解决问题。是否可以将平均聚合作为表中的一列?

标签: cassandra cql


【解决方案1】:

Cassandra 只能通过聚类列对结果进行排序。它不能按聚合函数对结果进行排序。

您可以查看几个选项来完成此操作。

  1. 进行查询,然后在您的应用程序中重新排序结果。

如果您只希望从每个查询中返回有限数量的行,此选项可能会起作用。

请注意,当您知道聚合函数(如 avg())仅适用于有限数量的行时,建议您只使用它。理想情况下,您应该只在对单个分区进行操作时使用它们(使用 WHERE 子句限制为单个分区)。如果您没有任何限制,您可能会看到非常慢的查询,或者如果 Cassandra 需要读取大量行以计算聚合,则查询超时。

  1. 将预先计算的平均值存储在表中,或将其缓存在您的应用程序中。

如果您需要在更大的数据集上计算平均值,这是最佳选择。

如果您将average_rating 设为集群列,Cassandra 将按排序顺序存储每个分区的平均值。从 Cassandra 的角度来看,这非常有效。

缺点是每次插入或更新行时都需要在应用程序中计算平均值,因为它将是 Cassandra 表中的主键列。

您可以研究的一件事是使用 Cassandra 触发器为您计算平均值。如果您有多个应用程序写入此表,这可能会使您的生活更轻松,但是我实际上不确定是否可以通过自定义触发器修改主键列。如果您决定查看此选项,我建议您进行一些研究和测试。您可以阅读有关触发器的信息here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多