4

行キーで複合データ型を使用しています。列ファミリーは以下のとおりです

create column family CompositeTest
with comparator = 'UTF8Type'
and key_validation_class = 'CompositeType(UTF8Type,UTF8Type)'
and default_validation_class = 'UTF8Type';

この列ファミリーのサンプル データは次のとおりです。

RowKey: s2:2222222
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3
-------------------
RowKey: s2:3333333
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3
-------------------
RowKey: s2:1111111
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3
-------------------
RowKey: s1:3333333
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3
-------------------
RowKey: s1:2222222
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3
-------------------
RowKey: s1:1111111
=> (column=param1, value=value1
=> (column=param2, value=value2
=> (column=param3, value=value3

行キーの最初のコンポーネントが「s1」であるすべての行を取得したい。Hector クライアントを使用することは可能ですか? そうでない場合、どのcassandraクライアントで可能ですか?

次のコードを使用して試しましたが、機能しません。

Composite start = new Composite();
        start.addComponent(0, "s1", ComponentEquality.EQUAL);

        Composite end = new Composite();
        end.addComponent(0, "s1", ComponentEquality.GREATER_THAN_EQUAL);

        RangeSlicesQuery<Composite, String, String> rangeSlicesQuery = HFactory.createRangeSlicesQuery(keyspace, new CompositeSerializer(), StringSerializer.get(),  StringSerializer.get()); 
        rangeSlicesQuery.setKeys(start, end);
        rangeSlicesQuery.setRange("param1", "param3", false, 100);
        rangeSlicesQuery.setColumnFamily("CompositeTest");
        rangeSlicesQuery.setRowCount(11);
        QueryResult<OrderedRows<Composite, String, String>>  queryResult = rangeSlicesQuery.execute();

        Rows<Composite, String, String> rows = queryResult.get();
        Iterator<Row<Composite, String, String>> rowsIterator = rows.iterator();

前もって感謝します...

4

2 に答える 2

2

これは、クライアントを使用する Cassandra では不可能です。行キーはアプリケーション開発者には複合オブジェクトとして表示されますが、Cassandra 自体では行キーは単一のバイト配列であり、Cassandra の SSTable に単一のアトミック値として格納されます。

つまり、キーの一部だけでなく、キー全体でのみ行をクエリできます。そうしないと、一致するものが見つかるまで列ファミリー全体をスキャンする必要があり、非常にコストがかかります。

そうは言っても、行キーの一部のみを使用して列ファミリー内の行をクエリできるようにする必要がある場合は、それらのキー部分に対して個別のインデックス列ファミリーを作成することを強くお勧めします。これにより、標準のキー/列ルックアップを使用して、基準に一致する生データ列ファミリーのすべての行を見つけることができます。

于 2013-11-13T23:18:05.233 に答える
1

問題は、行キーでスライスを実行しようとしていることです。Cassandra でランダム パーティショナー (RandomPartitioner や Murmur3Partitioner など) を使用している場合は、まったく不可能です。順序を維持するパーティショナーを使用している場合は、可能かもしれません (ただし、試したことはありません)。あなたの場合、不運が存在しない CompositeKeyPartitioner である必要があるため、自分で作成する必要があります。次に、データに従って適切なトークンを計算して、クラスターを構成する必要もあります。ご覧のとおり、これは最も簡単な方法ではありません。

ただし、キーの代わりに列名に複合値を入れるだけで、同じことができます。次のように CF を定義できます。

create column family CompositeTest
   with comparator = 'CompositeType(UTF8Type,UTF8Type)'
   and key_validation_class = 'UTF8Type'
   and default_validation_class = 'UTF8Type';

そして、次のようなデータを保存します。

RowKey: s2
=> (column=2222222:param1, value=value1
=> (column=2222222:param2, value=value2
=> (column=2222222:param3, value=value3
=> (column=3333333:param1, value=value1
=> (column=3333333:param2, value=value2
=> (column=3333333:param3, value=value3
=> (column=1111111:param1, value=value1
=> (column=1111111:param2, value=value2
=> (column=1111111:param3, value=value3
-------------------
RowKey: s1:
=> (column=3333333:param1, value=value1
=> (column=3333333:param2, value=value2
=> (column=3333333:param3, value=value3
=> (column=2222222:param1, value=value1
=> (column=2222222:param2, value=value2
=> (column=2222222:param3, value=value3
=> (column=1111111:param1, value=value1
=> (column=1111111:param2, value=value2
=> (column=1111111:param3, value=value3

この構造を使用すると、クエリは非常に簡単だと思います。その後、いつでも列名をスライスして、必要な間隔内の列のみを選択できます。

于 2013-11-15T09:43:42.693 に答える