Cassandra: Inserting column in cassandra table - cassandra

I am trying to insert new column in Cassandra table.
Column Name- feedback_map
Column type- map of text, feedback_map
And trying to execute this statement.
ALTER TABLE my_table ADD feedback_map map<text, frozen<feedback_details>>;
but getting unknown type error on feedback_details
Am pretty new to cassandra.
I am having custom feedback_details user type with two field-
#Field(name = "field_mappings")
private Map<String, String> fieldMappings;
#Field(name = "field_defaults")
private Map<String, String> fieldDefaults;
No i have not defined it yet? do i need to add this user type to my table first??

First, make sure that your User Defined Type (UDT) exists. If not, you'll need to create it:
CREATE TYPE feedback_details (
field_mappings MAP<TEXT, TEXT>,
field_defaults MAP<TEXT, TEXT>);
Then you'll be able to add it as a column on your table (as you have above):
ALTER TABLE my_table ADD feedback_map map<text, frozen<feedback_details>>;

Related

Convert single UDT object to list of UDT in Cassandra table

I have two userdefined type in Cassandra. First one is using the second object as frozen object inside it.
CREATE TYPE my_keyspace.test (
testid text,
testdate text,
testdata frozen<testdata>
);
CREATE TYPE my_keyspace.testdata (
subject text,
metadata text
);
Now my requirement is to convert this single object to list of UDT . Something like this
CREATE TYPE my_keyspace.test (
testid text,
testdate text,
testdata list<frozen<testdata>>
);
Is it possible to update single object to list of object in Cassandra. Whata are options available to update the schema.
The only way to do it, is to add another field with required type using the ALTER TYPE, and start to use this new field, migrating existing data using some code. Cassandra doesn't allow to change type of the existing fields, and you can't also drop a field from UDT. So your type should be something like this:
CREATE TYPE my_keyspace.test (
testid text,
testdate text,
testdata frozen<testdata>
testdata_lst list<frozen<testdata>>
);
Existing data could be migrated into a list, and then set to null to free the space.

Yugabyte YCQL check if a set contain a value?

Is there there any way to query on a SET type(or MAP/LIST) to find does it contain a value or not?
Something like this:
CREATE TABLE test.table_name(
id text,
ckk SET<INT>,
PRIMARY KEY((id))
);
Select * FROM table_name WHERE id = 1 AND ckk CONTAINS 4;
Is there any way to reach this query with YCQL api?
And can we use a SET type in SECONDRY INDEX?
Is there any way to reach this query with YCQL api?
YCQL does not support the CONTAINS keyword yet (feel free to open an issue for this on the YugabyteDB GitHub).
One workaround can be to use MAP<INT, BOOLEAN> instead of SET<INT> and the [] operator.
For instance:
CREATE TABLE test.table_name(
id text,
ckk MAP<int, boolean>,
PRIMARY KEY((id))
);
SELECT * FROM table_name WHERE id = 'foo' AND ckk[4] = true;
And can we use a SET type in SECONDRY INDEX?
Generally, collection types cannot be part of the primary key, or an index key.
However, "frozen" collections (i.e. collections serialized into a single value internally) can actually be part of either primary key or index key.
For instance:
CREATE TABLE table2(
id TEXT,
ckk FROZEN<SET<INT>>,
PRIMARY KEY((id))
) WITH transactions = {'enabled' : true};
CREATE INDEX table2_idx on table2(ckk);
Another option is to use with compound primary key and defining ckk as clustering key:
cqlsh> CREATE TABLE ybdemo.tt(id TEXT, ckk INT, PRIMARY KEY ((id), ckk)) WITH CLUSTERING ORDER BY (ckk DESC);
cqlsh> SELECT * FROM ybdemo.tt WHERE id='foo' AND ckk=4;

Using MATERIALIZED VIEW in Cassandra gives error

I have following table.
CREATE TABLE test_x (id text PRIMARY KEY, type frozen<mycustomtype>);
mycustomtype is defined as follows,
CREATE TABLE mycustomtype (
id uuid PRIMARY KEY,
name text
)
And i have created following materialized view for queries based on mycustometype filed.
CREATE MATERIALIZED VIEW test_x_by_mycustomtype_name AS
SELECT id, type
FROM test_x
WHERE type IS NOT NULL
PRIMARY KEY (id, type)
WITH CLUSTERING ORDER BY (type ASC)
With above view i hope to execute following query.
select id from test_x_by_mycustomtype_name where type =
{id: a3e64f8f-bd44-4f28-b8d9-6938726e34d4, name: 'Sample'};
But the query fails saying i need to use 'ALLOW FILTERING'. I created the view not to use ALLOW FILTERING. Why this error is happening here since i have used the part of primary key of the view ?
In you view, the type column is still clustering key. Hence, ALLOW FILTER should be used. You can change the view as per below and retry
CREATE MATERIALIZED VIEW test_x_by_mycustomtype_name_2 AS
SELECT id, type
FROM test_x
WHERE type IS NOT NULL
PRIMARY KEY (type, id)
WITH CLUSTERING ORDER BY (id ASC);
cqlsh:test> select id from test_x_by_mycustomtype_name_2 where type = {id: a3e64f8f-bd44-4f28-b8d9-6938726e34d4, name: 'Sample'};
id
----
Change the order of the primary key of materialized view
CREATE MATERIALIZED VIEW test_x_by_mycustomtype_name AS
SELECT id, type
FROM test_x
WHERE type IS NOT NULL
PRIMARY KEY (type, id)
WITH CLUSTERING ORDER BY (type ASC);

Cassandra: Inserting value in UDT

I am trying to insert values in UDT but getting error message -
message="unconfigured columnfamily my_object"
below my statement-
INSERT INTO home.my_object (id,type,quantity ,critical,page_count,stock,outer_envelope ) VALUES ('3.MYF','COM','D','A','VV','','');
What am i doing wrong?
That error means that the keyspace "home" exists, but does not contain a table (column family) called "my_object". I also noticed that your insert statement does not contain a UDT literal.
UDTs define a type, but you must also define a table with a column of that type before inserting any data. I assume your UDT is called "my_object". Try this:
create table home.test (key int primary key, object frozen<my_object>);
insert into home.test (key, object) values (0, {id: 'value', type: 'othervalue'});

creating uuid type field in Cassandra table using CassandraAdminOperations.createTable

I have problem when create table with UUID type field using CassandraAdminOperations.createTable. I defined field in table with type uuid, but when the table was created using CassandraAdminOperations.createTable, the field was created as timeuuid. Is there any way to force the field to uuid instead of timeuuid ?
Here is the field definition in class,
#PrimaryKeyColumn(name = "id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
private UUID id;
#Column(value = "url")
private String url;
But when call CassandraAdminOperations.createTable to create the table, the log shows the following and the id filed was created as timeuuid,
00:43:23.877 [localhost-startStop-1] DEBUG o.s.d.c.core.CassandraAdminTemplate - CREATE TABLE IF NOT EXISTS id_to_url_map (id timeuuid, url text, PRIMARY KEY (id));
Thanks!
I had the same problem. But after some investigation, I found that you can add #CassandraType annotation, and explicitly specify the class.
import com.datastax.driver.core.DataType;
#PrimaryKeyColumn(name = "id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
#CassandraType(type = DataType.Name.UUID)
private UUID id;

Resources