Cassandra Invalid Query: Some cluster keys are missing - cassandra

I'm using Cassandra 3.0.
My table was created with this query, but when I try to insert data into the table, I get the error: 'Some cluster keys are missing: created'
Table Structure:
CREATE TABLE db.feed (
action_object_id int,
owner_id int,
created timeuuid,
action_object text,
action_object_type int,
actor text,
feed_type text,
target text,
target_type int,
verb text,
PRIMARY KEY (action_object_id, owner_id, created)
) WITH CLUSTERING ORDER BY (owner_id ASC, created ASC)

You must have to provide values for all the primary keys. action_object_id, owner_id, created must have to be mentioned in your insert query.
Ex: insert into db.feed(action_object_id, owner_id, created, ...) values (?,?,?,...). And you cannot provide NULL values for primary keys. created cannot be null.

Related

Not able to run multiple where clause without Cassandra allow filtering

Hi I am new to Cassandra.
We are working on IOT project where car sensor data will be stored in cassandra.
Here is the example of one table where I am going to store one of the sensor data.
This is some sample data.
The way I want to partition the data is based on the organization_id so that different organization data is partitioned.
Here is the create table command:
CREATE TABLE IF NOT EXISTS engine_speed (
id UUID,
engine_speed_rpm text,
position int,
vin_number text,
last_updated timestamp,
organization_id int,
odometer int,
PRIMARY KEY ((id, organization_id), vin_number)
);
This works fine. However all my queries will be as bellow:
select * from engine_speed
where vin_number='xyz'
and organization_id = 1
and last_updated >='from time stamp' and last_updated <='to timestamp'
Almost all queries in all the table will have similar / same where clause.
I am getting error and it is asking to add "Allow filtering".
Kindly let me know how do I partition the table and define right primary key and indexs so that I don't have to add "allow filtering" in the query.
Apologies for this basic question but I'm just starting using cassandra.(using apache cassandra:3.11.12 )
The order of where clause should match with the order of partition and clustering keys you have defined in your DDL and you cannot skip any part of primary key while applying the WHERE clause before using the next key. So as per the query pattern u have defined, you can try the below DDL:
CREATE TABLE IF NOT EXISTS autonostix360.engine_speed (
vin_number text,
organization_id int,
last_updated timestamp,
id UUID,
engine_speed_rpm text,
position int,
odometer int,
PRIMARY KEY ((vin_number, organization_id), last_updated)
);
But remember,
PRIMARY KEY ((vin_number, organization_id), last_updated)
PRIMARY KEY ((vin_number), organization_id, last_updated)
above two are different in Cassandra, In case 1 your data will be partitioned by combination of vin_number and organization_id while last_updated will act as ordering key. In case 2, your data will be partitioned only by vin_number while organization_id and last_updated will act as ordering key. So you need to figure out which case suits your use case.

Materialised view error in Cassandra

I am new to Cassandra, I am trying to create a table and materialized view. but it not working.
My queries are:
-- all_orders
create table all_orders (
id uuid,
order_number bigint,
country text,
store_number bigint,
supplier_number bigint,
flow_type int,
planned_delivery_date timestamp,
locked boolean,
primary key ( order_number,store_number,supplier_number,planned_delivery_date ));
-- orders_by_date
CREATE MATERIALIZED VIEW orders_by_date AS
SELECT
id,
order_number,
country,
store_number,
supplier_number,
flow_type,
planned_delivery_date,
locked,
FROM all_orders
WHERE planned_delivery_date IS NOT NULL AND order_number IS NOT NULL
PRIMARY KEY ( planned_delivery_date )
WITH CLUSTERING ORDER BY (store_number,supplier_number);
I am getting an exception like this:
SyntaxException: <ErrorMessage code=2000 [Syntax error in CQL query]
message="line 1:7 no viable alternative at input 'MATERIALIZED' ([CREATE] MATERI
ALIZED...)">
Materialized Views in Cassandra solves the use case of not having to maintain additional table(s) for querying by different partition keys. But comes with following restrictions
Use all base table primary keys in the materialized view as primary keys.
Optionally, add one non-PRIMARY KEY column from the base table to the
materialized view's PRIMARY KEY.
Static columns are not supported as a PRIMARY KEY.
More documentation reference here.
So the correct syntax in your case of adding the materialized view would be
CREATE MATERIALIZED VIEW orders_by_date AS
SELECT id,
order_number,
country,
store_number,
supplier_number,
flow_type,
planned_delivery_date,
locked
FROM all_orders
WHERE planned_delivery_date IS NOT NULL AND order_number IS NOT NULL AND store_number IS NOT NULL AND supplier_number IS NOT NULL
PRIMARY KEY ( planned_delivery_date, store_number, supplier_number, order_number );
Here planned_delivery_date is the partition key and the rows are ordered by store_number, supplier_number, order_number (essentially the clustering columns). So there isn't a mandatory requirement to add "CLUSTERING ORDER BY" clause here.

Columns ordering in Cassandra

When I create a table in CQL, is it necessary to be exact for the order of column that are NOT in the primary_key and NOT clustering columns :
CREATE TABLE user (
a ascii,
b ascii,
c ascii,
PRIMARY KEY (a)
);
Is it equivalent to ?
CREATE TABLE user (
a ascii,
c ascii, <-- switched
b ascii, <-- switched
PRIMARY KEY (a)
);
Thank you for your help
Both of those statements will fail, because of:
The extra comma.
You have not provided a primary key definition.
Assuming you had those fixed, then the answer is still "yes they are the same."
Cassandra applies its own order to your columns at table creation time. Consider this table as I have typed it:
CREATE TABLE testorder (
acolumn text,
jcolumn text,
dcolumn text,
bcolumn text,
apkey text,
bpkey text,
ackey text,
bckey text,
PRIMARY KEY ((bpkey,apkey),bckey,ackey));
After creating it, I'll describe the table so you can see the order that Cassandra has applied to the columns.
aploetz#cqlsh:stackoverflow> desc table testorder ;
CREATE TABLE stackoverflow.testorder (
bpkey text,
apkey text,
bckey text,
ackey text,
acolumn text,
bcolumn text,
dcolumn text,
jcolumn text,
PRIMARY KEY ((bpkey, apkey), bckey, ackey)
) WITH CLUSTERING ORDER BY (bckey ASC, ackey ASC)
Essentially, Cassandra will order the partition keys and the clustering keys (ordered by their precedence in the PRIMARY KEY definition), and then the columns follow in ascending order.

Non-EQ relation error Cassandra - how fix primary key?

I created a one table posts. When I make request SELECT:
return $this->db->query('SELECT * FROM "posts" WHERE "id" IN(:id) LIMIT '.$this->limit_per_page, ['id' => $id]);
I get error:
PRIMARY KEY column "id" cannot be restricted (preceding column
"post_at" is either not restricted or by a non-EQ relation)
My table dump is:
CREATE TABLE posts (
id uuid,
post_at timestamp,
user_id bigint,
name text,
category set<text>,
link varchar,
image set<varchar>,
video set<varchar>,
content map<text, text>,
private boolean,
PRIMARY KEY (user_id,post_at,id)
)
WITH CLUSTERING ORDER BY (post_at DESC);
I read some article about PRIMARY AND CLUSTER KEYS, and understood, when there are some primary keys - I need use operator = with IN. In my case, i can not use a one PRIMARY KEY. What you advise me to change in table structure, that error will disappear?
My dummy table structure
CREATE TABLE posts (
id timeuuid,
post_at timestamp,
user_id bigint,
PRIMARY KEY (id,post_at,user_id)
)
WITH CLUSTERING ORDER BY (post_at DESC);
And after inserting some dummy data
I ran query select * from posts where id in (timeuuid1,timeuuid2,timeuuid3);
I was using cassandra 2.0 with cql 3.0

ORDER BY with 2ndary indexes is not supported

I am using cassandra 2.1 with latest CQL.
Here is my table & indexes:
CREATE TABLE mydata.chats_new (
id bigint,
adid bigint,
fromdemail text,
fromemail text,
fromjid text,
messagebody text,
messagedatetime text,
messageid text,
messagetype text,
todemail text,
toemail text,
tojid text,
PRIMARY KEY(messageid,messagedatetime)
);
CREATE INDEX user_fromJid ON mydata.chats_new (fromjid);
CREATE INDEX user_toJid ON mydata.chats_new (tojid);
CREATE INDEX user_adid ON mydata.chats_new (adid);
When i execute this query:
select * from chats_new WHERE fromjid='test' AND toJid='test1' ORDER BY messagedatetime DESC;
I got this error:
code=2200 [Invalid query] message="ORDER BY with 2ndary indexes is not supported."
So how should fetch this data?
select * from chats_new
WHERE fromjid='test' AND toJid='test1'
ORDER BY messagedatetime DESC;
code=2200 [Invalid query] message="ORDER BY with 2ndary indexes is not supported."
To get the WHERE clause of this query to work, I would build a specific query table, like this:
CREATE TABLE mydata.chats_new_by_fromjid_and_tojid (
id bigint,
adid bigint,
fromdemail text,
fromemail text,
fromjid text,
messagebody text,
messagedatetime text,
messageid text,
messagetype text,
todemail text,
toemail text,
tojid text,
PRIMARY KEY((fromjid, tojid), messagedatetime, messageid)
);
Note the primary key definition. This creates a partitioning key out of fromjid and tojid. While this will allow you to query on both fields, it will also require both fields to be specified in all queries on this table. But that's why they call it a "query table", as it is generally designed to serve one particular query.
As for the remaining fields in the primary key, I kept messagedatetime as the first clustering column, to assure on-disk sort order. Default ordering in Cassandra is ascending, so if you want to change that at query time, that's where your ORDER BY messagedatetime DESC comes into play. And lastly, I made sure that the messageid was the second clustering column, to help ensure primary key uniqueness (assuming that messageid is unique).
Now, this query will work:
select * from chats_new_by_fromjid_and_tojid
WHERE fromjid='test' AND toJid='test1'
ORDER BY messagedatetime DESC;
If you need to query this data by additional criteria, I highly recommend that you create additional query table(s). Remember, Cassandra works best with tables that are specifically designed for each query they serve. It's ok to replicate your data a few times, because disk space is cheap...operation time is not.
Also, DataStax has a great article on when not to use a secondary index. It's definitely worth a read.

Resources