Cassandra=をWebアプリで初めて使用し、クエリの問題が発生しました。これが私のタブです。
CREATE TABLE vote (
doodle_id uuid,
user_id uuid,
schedule_id uuid,
vote int,
PRIMARY KEY ((doodle_id), user_id, schedule_id)
);
すべてのリクエストで、パーティションキーdoodle_idを指定します。たとえば、私は何の問題もなく作ることができます:
select * from vote where doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 and user_id = 97a7378a-e1bb-4586-ada1-177016405142;
しかし、私が行った最後のリクエストで:
select * from vote where doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 and schedule_id = c37df0ad-f61d-463e-bdcc-a97586bea633;
次のエラーが発生しました:
Bad Request: PRIMARY KEY column "schedule_id" cannot be restricted (preceding column "user_id" is either not restricted or by a non-EQ relation)
私はCassandraを使い始めたばかりですが、間違っている場合は修正してください。複合主キーでは、最初の部分はパーティションキーです。これはCassandraを検索する場所を知るために必須です。次に、その他の部分はデータをソートするためのクラスタリングキーです。
しかし、なぜ私の最初のリクエストが機能し、2番目のリクエストが機能しないのかわかりませんか?
誰かが助けてくれるなら、それは大きな喜びです。
Cassandraでは、クエリに合うようにデータモデルを設計する必要があります。したがって、2番目のクエリ(doodle_id
とschedule_id
によるクエリ、ただしuser_id
で必ずしも必要ではない)をサポートする適切な方法は、その特定のクエリを処理する新しいテーブルを作成することです。このテーブルは、PRIMARY KEYが少し異なることを除いて、ほとんど同じです。
CREATE TABLE votebydoodleandschedule (
doodle_id uuid,
user_id uuid,
schedule_id uuid,
vote int,
PRIMARY KEY ((doodle_id), schedule_id, user_id)
);
これでこのクエリは機能します。
SELECT * FROM votebydoodleandschedule
WHERE doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7
AND schedule_id = c37df0ad-f61d-463e-bdcc-a97586bea633;
これにより、ALLOW FILTERING
を指定する必要がなくなります。 ALLOW FILTERING
に依存することは決して良い考えではなく、本番クラスターで行うべきことではありません。
クラスタリングキーは、特定のパーティション内の列を見つけるためにも使用されます。モデルを使用すると、次の方法でクエリを実行できます。
ALLOW FILTERING
を使用したuser_idALLOW FILTERING
を使用したuser_id/schedule_id主キーはファイルパスdoodle_id#123/user_id#456/schedule_id#789として見ることができます。ここで、すべてのデータは最も深いフォルダー(つまり、schedule_id#789)に保存されます。クエリを実行するときは、検索を開始するサブフォルダー/サブツリーを指定する必要があります。
列がパーティション内でどのように編成されているかが原因で、2番目のクエリは機能しません。 Cassandraは、インターリーブされているため、パーティション内の列の連続スライスを取得できません。
クエリを実行できるようにするには、主キーの順序(doodle_id、schedule_id、user_id)を逆にする必要があります。