Cassandra数据建模设计

时间:2015-07-31 10:21:52

标签: cassandra

我对Cassandra很新,并且在过去一个月里一直在阅读。
我正在研究一个小用例。
查询:基于TimeRange中AmountPlayed的前X个玩家。

因此,在任何给定的时间范围内,我都希望聚合玩家TotalAmountPlayed并派遣前X名玩家。

我遵循创建UDF(使用C * -2.2.0版本)的方法,以便播放器对AmountPlayed进行聚合。

以下是我为此用例设计的时间序列数据模型。

CREATE COLUMNFAMILY PlayerRating
(
PlayerNumber int, ===> Unique account number
GameID text, ===> unique machine ID per slot
AmountPlayed double, ===> AmountPlayed by the player
EventTime timestamp, ===> Event generated TimeStamp
PRIMARY KEY ((PlayerNumber, GameID),EventTime)) WITH CLUSTERING ORDER BY(EventTime desc);

如果我的数据模型设计适合我的查询,请告诉我。

谢谢!!

1 个答案:

答案 0 :(得分:1)

我认为将每个游戏的所有玩家放入一个分区可能更容易。

通过这种方式,您可以使用一个查询聚合所有玩家,而不是为每个玩家单独查询。然后你可以将每个玩家的上场时间聚合成一个地图(参见如何为here定义UDF的例子)。

所以你的表看起来像这样:

CREATE TABLE playing_time_by_game (game_id text, event_time int, player_id text, amount_played int, PRIMARY KEY (game_id, event_time));

然后通过player_id创建UDF总计:

CREATE FUNCTION state_group_and_total( state map<text, int>, type text, amount int )
     CALLED ON NULL INPUT
     RETURNS map<text, int>
     LANGUAGE java AS '
     Integer count = (Integer) state.get(type);  if (count == null) count = amount; else count = count + amount; state.put(type, count); return state; ' ;

然后创建聚合函数:

CREATE OR REPLACE AGGREGATE group_and_total(text, int) 
     SFUNC state_group_and_total 
     STYPE map<text, int> 
     INITCOND {};

然后插入一些数据:

SELECT * from playing_time_by_game ;

 game_id | event_time | amount_played | player_id
---------+------------+---------------+-----------
   game1 |          0 |             8 |   player1
   game1 |          1 |            12 |   player2
   game1 |          5 |             1 |   player2
   game1 |          8 |            50 |   player1
   game2 |          0 |           200 |   player1

现在你可以通过player_id聚合:

SELECT group_and_total(player_id, amount_played) from playing_time_by_game;

 t2.group_and_total(player_id, amount_played)
----------------------------------------------
              {'player1': 258, 'player2': 13}

您可以将查询限制在游戏分区和时间范围内:

SELECT group_and_total(player_id, amount_played) from playing_time_by_game where game_id='game1' and event_time >=0 and event_time <=7;

 t2.group_and_total(player_id, amount_played)
----------------------------------------------
                {'player1': 8, 'player2': 13}

你可能还可以定义一个FINALFUNC来排序并保留地图中的前十个项目。请参阅this

相关问题