というようなことをする為にクエリを書く。もっと良い書き方があるような気もする。
StackOverFlowを見たらRankを使おうみたいなことが書いてあったけど、サンプルがうまく動かなかったのでROW_NUMBERを使用。0.11以降実装されているらしい。
下記クエリの仕様は、page_id, user_idが記述されているアクセスログ的なテーブルを集計して、各page_idを訪れているuser_id上位10件を出すものとする。page_idはurl encodeする。
SELECT
REFLECT("java.net.URLEncoder", "encode", page_id),
COLLECT_ALL( user_id )
FROM
(
SELECT
page_id,
user_id,
ROW_NUMBER() OVER ( PATITION BY page_id ORDER BY cnt DESC ) AS rank
FROM
(
SELECT
page_id,
user_id,
COUNT(1) AS cnt
FROM
access_log
GROUP BY
page_id,
user_id
) a
DISTRIBUTE BY
page_id,
user_id
) b
WHERE
rank <= 10
GROUP BY
page_id,
user_id
実際に動かしたクエリからいろいろ改変しているので、このままだと動かないかもしれない。でもイメージはだいたいこんな感じで想定した動きになった。
以下、使っている機能の説明。
REFLECT : Javaのメソッドを直接呼び出す。int, double, string等の基本的なクラスしか引数に渡せない。 COLLECT_ALL : GROUP BYした結果をarrayに展開する。類似の機能にcollect_setなどもある。 ROW_NUMBER : 名前の通りROWにNUMBERを振る。 DISTRIBUTE BY : 同一のReducerで処理するよう指定する。