如何获得cassandra 2.2中的前5条记录

我需要帮助。 我有一个查询,按日期(不是日期+时间)和金额总和获得前5名记录组。

我写了以下内容,但它返回的所有记录不仅仅是前5条记录

CREATE OR REPLACE FUNCTION state_groupbyandsum( state map, datetime text, amount text ) CALLED ON NULL INPUT RETURNS map LANGUAGE java AS 'String date = datetime.substring(0,10); Double count = (Double) state.get(date); if (count == null) count = Double.parseDouble(amount); else count = count + Double.parseDouble(amount); state.put(date, count); return state;' ; CREATE OR REPLACE AGGREGATE groupbyandsum(text, text) SFUNC state_groupbyandsum STYPE map INITCOND {}; select groupbyandsum(datetime, amout) from warehouse; 

你能帮忙得到5条记录吗?

这是一种方法。 您按州的function可以是这样的:

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

这将构建一个由查询WHERE子句选择的所有金额行的映射。 现在最棘手的部分是如何保持前N个。一种方法是使用FINALFUNC,它在所有行放入地图后执行。 所以这是一个函数来使用循环来查找地图中的最大值并将其移动到结果映射。 因此,为了找到前N个,它将在地图上迭代N次(有比这更有效的算法,但它只是一个快速而肮脏的例子)。

所以这是一个找到前两个的例子:

 CREATE FUNCTION topFinal (state map) CALLED ON NULL INPUT RETURNS map LANGUAGE java AS ' java.util.Map inMap = new java.util.HashMap(), outMap = new java.util.HashMap(); inMap.putAll(state); int topN = 2; for (int i = 1; i <= topN; i++) { double maxVal = -1; String moveKey = null; for (java.util.Map.Entry entry : inMap.entrySet()) { if (entry.getValue() > maxVal) { maxVal = entry.getValue(); moveKey = entry.getKey(); } } if (moveKey != null) { outMap.put(moveKey, maxVal); inMap.remove(moveKey); } } return outMap; '; 

最后,您需要定义AGGREGATE以调用您定义的两个函数:

 CREATE OR REPLACE AGGREGATE group_and_total(text, double) SFUNC state_group_and_total STYPE map FINALFUNC topFinal INITCOND {}; 

那么让我们看看是否有效。

 CREATE table test (partition int, clustering text, amount double, PRIMARY KEY (partition, clustering)); INSERT INTO test (partition , clustering, amount) VALUES ( 1, '2015', 99.1); INSERT INTO test (partition , clustering, amount) VALUES ( 1, '2016', 18.12); INSERT INTO test (partition , clustering, amount) VALUES ( 1, '2017', 44.889); SELECT * from test; partition | clustering | amount -----------+------------+-------- 1 | 2015 | 99.1 1 | 2016 | 18.12 1 | 2017 | 44.889 

现在,鼓滚……

 SELECT group_and_total(clustering, amount) from test where partition=1; agg.group_and_total(clustering, amount) ------------------------------------------- {'2015': 99.1, '2017': 44.889} 

所以你看它根据金额保留了前2行。

请注意,键不是按排序顺序,因为它是一个映射,我认为我们不能控制映射中的键顺序,因此在FINALFUNC中排序将浪费资源。 如果您需要排序的地图,那么您可以在客户端中执行此操作。

我认为你可以在state_group_and_total函数中做更多的工作,以便在你继续时从地图中删除项目。 这可能会更好地防止地图变得太大。