Cassandra は、行キー以外でクエリできるデータベースではありません。ただし、これらのクエリをサポートするようにデータモデルを調整できます。
6 つの cassandra ノード クラスターで 1 日に 1 億 7,500 万件のクエリを実行します (簡単です!) が、データモデルをそのように動作させるため、row_keys と列を使用してデータを要求するだけです。インデックス付きクエリは使用しません。
より豊富なクエリをサポートするために、データを取得するためのキーを作成するための検索パラメーターとして使用するデータを使用して、データを非正規化します。
例:次のオブジェクトを保存するとします。
obj {
id : xxx //assuming id is a unique id across the system
p1 : value1
p2 : value2
}
そして、これらのパラメーターのいずれかで検索したいことがわかっているので、次のように、column_names またはキーの obj のコピーを保存します。
"p1:value1:xxx"
"p2:value2:xxx"
"p1:value1:p2:value2:xxx"
"xxx"
このようにして、p1 = value1、p2 =value2、p1 = value1 AND p2 = value2、または一意の ID xxx だけで obj を検索できます。
それをしたくない場合の唯一の他のオプションは、セカンダリインデックスとインデックス付きクエリを使用することですが、それは質問の「スキーマレス」要件を失います。
編集 - 例。
として定義されたオブジェクト「製品」を保存したい
class Products{
string uid;
string name;
int screen_size; //in inches
string os;
string brand;
}
それを文字列または byteArray にシリアル化します (私は常に Jackson Json または Protobuf を使用する傾向があります...どちらも cassandra で非常にうまく機能し、超高速です)。そのバイト配列を列に入れます。
ここで重要なのは、列名と行キーを作成することです。画面の解像度で検索し、場合によってはブランドでフィルタリングしたいとしましょう。画面サイズのバケットを ["0_to15", "16_to_21", "21_up"] として定義します
指定された列:
"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}
1 つのコピーが保存されます: - key = "brand:Samsung" and column_name = "screen_size:15_uid:MI615FMDO548" - key = "brand:0_to_15" and column_name = "screen_size:15_uid:MI615FMDO548"
列名に uid を追加するのはなぜですか? 固有の製品に対してすべての列名を固有にするため。
例のパート 2では、追加したとしましょう
"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
"{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}"
"{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
"{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"
最終的に、次の列ファミリーになります。
Products{
-Row:"brand:Samsung"
=> "screen_size:13_uid:MI615FMDO687":"{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"
=> "screen_size:14_uid:MI615FMD5589":"{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}
=> "screen_size:15_uid:MI615FMDO548":"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
=> "screen_size:17_uid:MI615FMD1111":"{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
-Row:"screen_size:0_to_15"
=> "brand:Samsung_uid:MI615FMDO687":"{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"
=> "brand:Samsung_uid:MI615FMD5589":"{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}
=> "brand:Samsung_uid:MI615FMDO548":"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
-Row:"screen_size:16_to_17"
=> "brand:Samsung_uid:MI615FMD1111":"{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
-Row:"uid:MI615FMDO687"
=> "product":"{uid:"MI615FMDO687", name:"SFG-0095", screen_size:13, os:"Android JellyBean", brand:"Samsung"}"
-Row:"uid:MI615FMD5589"
=> "product":"{uid:"MI615FMD5589", name:"SFG-0097", screen_size:14, os:"Android JellyBean", brand:"Samsung"}
-Row:"uid:MI615FMDO548"
=> "product":"{uid:"MI615FMDO548", name:"SFG-0098", screen_size:15, os:"Android JellyBean", brand:"Samsung"}"
-Row:"uid:MI615FMD1111"
=> "product":"{uid:"MI615FMD1111", name:"SFG-0098", screen_size:17, os:"Android JellyBean", brand:"Samsung"}"
}
列名全体で範囲クエリを使用することで、ブランドや画面サイズで検索できるようになりました。
これが役に立ったことを願っています