web-dev-qa-db-ja.com

MAX()、DISTINCT、およびCassandraでグループ化

SQLデータベースをリモデルしようとしていますCassandra Cassandra= SQLクエリと同等。CQL3およびCassandrav1.2。db設計をcassandraでモデル化したため、order by句と非正規化テーブルをサポートして、結合操作をサポートします。ただし、 DISTINCT、SUM()、およびGROUPBYと同等のものになります

SELECT a1,MAX(b1) FROM demo1 group by a1.
SELECT DISTINCT (a2) FROM demo2 where b2='sea'
SELECT sum(a3), sum(b3) from demo3 where c3='water' and d3='ocean'

これは、過去2日間の私の仕事の目玉です。 Cassandraには、これらの種類のクエリをサポートするためにdbスキーマをモデル化する方法がありますか?私はCassandra。ではどのような方法も考えられません。このようなクエリはCassandraを使用してどのように実装されますか?

私は、Cassandra上のHiveレイヤーがこれらのクエリを機能させる可能性があることを読みました。Cassandraでそのようなクエリをサポートできる唯一の方法かどうか疑問に思っています。可能な方法..

17
eldho

Cassandraは、このような操作をサポートしていません。上にHiveのようなものを使用するか、必要なことを行うAcunuの(無料でない)製品があります。

他の解決策は、自分で作業を行うことです。たとえば、特定の行からすべてのデータを読み込んで合計することで、物事を合計できます。またはCassandraカウンターをオンザフライでインクリメントします。

11
Richard

これは古い質問ですが、Googleの検索結果にはかなり多く表示されます。だから私は更新をしたかった。

Cassandra 2.2+は、ユーザー定義関数およびユーザー定義集計をサポートしています。 [〜#〜] warning [〜#〜]:これは、(先ほど指摘したように、データモデリングを行う必要がないという意味ではありません。 @Theo)ではなく、取得時にデータをわずかに前処理するだけです。

SELECT DISTINCT(a2)from demo2 where b2 = 'sea'

DISTINCTを実装するには、関数と集約を定義する必要があります。 uniqではなく関数と集約distinctの両方を呼び出して、ユーザー定義であることを強調します。

CREATE OR REPLACE FUNCTION uniq(state set<text>, val text)
  CALLED ON NULL INPUT RETURNS set<text> LANGUAGE Java
  AS 'state.add(val); return state;';
CREATE OR REPLACE AGGREGATE uniq(text)
  SFUNC uniq STYPE set<text> INITCOND {};

次に、次のように使用します。

SELECT uniq(a2) FROM demo2 where b2='sea';

SELECT sum(a3)、sum(b3)from demo3 where c3 = 'water' and d3 = 'ocean'

SUMはすぐに使用でき、期待どおりに機能します。 system.sumを参照してください。

SELECT a1、MAX(b1)FROM demo1 group by a1

GROUP BYは扱いにくいものです。実際には、結果の行を列ごとにグループ化する方法はありません。ただし、できることはmap<text, int>を作成し、それらをマップ内で手動でグループ化することです。 Christopher Bateyのブログ、group-byおよびmaxの例に基づきます:

CREATE OR REPLACE FUNCTION state_group_and_max(state map<text, int>, type text, amount int)
  CALLED ON NULL INPUT
  RETURNS map<text, int>
  LANGUAGE Java AS '
    Integer val = (Integer) state.get(type);
    if (val == null) val = amount; else val = Math.max(val, amount);
    state.put(type, val);
    return state;
  ' ;

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

次に、次のように使用します。

SELECT state_group_and_max(a1, b1) FROM demo1;

ノート

  • 前述のように、データモデリングに時間をかける必要がありますが、これらの機能を使いすぎないでください
  • 機能を有効にするには、enable_user_defined_functions=truecassandra.yamlを設定する必要があります
  • 関数をオーバーロードして、異なるタイプの列によるグループ化をサポートできます。

参照:

21
korya

Cassandra 3.10は、パーティションキーとクラスタリングキーによるグループ化をサポートするようになりました。詳細については このリンク を参照してください。

12
NangSaigon