Insert data in map<text,text> in cassandra db - cassandra

i have a column in cassandra database as map<text,text>
I insert the data in this table as :
INSERT INTO "Table1" (col1) VALUES ({'abc':'abc','hello':'world','flag':'true'});
So, in my code i can get the data as :
{
"abc":"abc",
"hello":"world",
"flag":"true"
}
But, now i want this like :
{
"abc":"abc",
"hello":"world",
"flag":{
"data":{ "hi":"cassandra"},
"working":"no"
}
}
For this, when I try the insert query, it says that it does not match the type map<text,text>
How can I make this work ?

The problem here (in your second example) is that the type of col1 is a map<text,text> but flag is a complex type and no longer matches that definition. One way to solve this would be to create individual TEXT columns for each property, as well as a user defined type for flag and the data it contains:
> CREATE TYPE flagtype (data map<text,text>,working text);
> CREATE TABLE table1 (abc text,
hello text,
flag frozen<flagtype>
PRIMARY KEY (abc));
Then INSERTing the JSON text from your second example works.
> INSERT INTO table1 JSON '{"abc":"abc",
"hello":"world",
"flag":{"data":{"hi":"cassandra"},
"working":"no"}}';
> SELECT * FROM table1;
abc | flag | hello
-----+--------------------------------------------+-------
abc | {data: {'hi': 'cassandra'}, working: 'no'} | world
(1 rows)
If you are stuck on using the map<text,text> type, and want the value JSON sub properties to be treated a large text string, you could try a simple table like this:
CREATE TABLE stackoverflow.table2 (
key1 text PRIMARY KEY,
col1 map<text, text>);
And on your INSERTs just escape out the inner quotes:
> INSERT INTO table2 JSON '{"key1":"1","col1":{"abc":"abc","hello":"world"}}';
> INSERT INTO table2 JSON '{"key1":"2","col1":{"abc":"abc","hello":"world",
"flag":"{\"data\":{\"hi\":\"cassandra\"},\"working\":\"no\"}"}}';
> SELECT * FROm table2;
key1 | col1
------+----------------------------------------------------------------------------------------
2 | {'abc': 'abc', 'flag': '{"data":{"hi":"cassandra"},"working":"no"}', 'hello': 'world'}
1 | {'abc': 'abc', 'hello': 'world'}
(2 rows)
That's a little hacky and will probably require some additional parsing on your application side. But it gets you around the problem of having to define each column.

Related

Get value from specific map-key in Cassandra

For example. I have a map under the column 'users' in a table called 'table' with primary key 'Id'.
If the map looks like this, {{'Phone': '1234567899'}, {'City': 'Dublin'}}, I want to get the value from key 'Phone' for specific 'Id', in Cassandra database.
Yes, that's possible to do with CQL when using a MAP collection.
To test this, I created a simple table using the specifications and data you mentioned above:
> CREATE TABLE stackoverflow.usermap (
id text PRIMARY KEY,
users map<text, text>);
> INSERT INTO usermap (id,users)
VALUES ('1a',{'Phone': '1234567899','City': 'Dublin'});
> SELECT * FROM usermap WHERE id='1a';
id | users
----+-------------------------------------------
1a | {'City': 'Dublin', 'Phone': '1234567899'}
(1 rows)
Then, I queried with the same WHERE clause, but altering my SELECT to pull back the user's phone only:
> SELECT users['Phone'] FROM usermap WHERE id='1a';
users['Phone']
----------------
1234567899
(1 rows)

Does last_insert_id() gives session specific value or global value across all sessions(multi-client environment)?

I have a table with AUTO_INCREMENT column in vertica db and using this column as foreign key for some other table. For that i need last inserted value for AUTO_INCREMENT column.
CREATE TABLE orders.order_test
(
order_id AUTO_INCREMENT(1,1,1) PRIMARY KEY,
order_type VARCHAR(255)
);
Found this function,but not sure how it works for multiple sessions?
https://www.vertica.com/docs/9.2.x/HTML/Content/Authoring/SQLReferenceManual/Functions/VerticaFunctions/LAST_INSERT_ID.htm
Above link says this:
Returns the last value of an AUTO_INCREMENT/IDENTITY column. If multiple sessions concurrently load the same table with an AUTO_INCREMENT/IDENTITY column, the function returns the last value generated for that column.
It is by session.
Let's test it.
Two command line windows. Starting vsql on both.
The transcript is the whole of the sessions.
Transaction 1:
sbx=> select export_objects('','id1',false);
CREATE TABLE dbadmin.id1
(
id IDENTITY ,
num int
);
[. . .]
sbx=> select * from id1;
id | num
--------+-----
250001 | 1
sbx=> \pset null NULL
Null display is "NULL".
sbx=> SELECT LAST_INSERT_ID();
LAST_INSERT_ID
----------------
NULL
-- insert a row ...
sbx=> INSERT INTO id1 (num) VALUES(2);
OUTPUT
--------
1
sbx=> SELECT LAST_INSERT_ID();
LAST_INSERT_ID
----------------
500001
Transaction 2:
sbx=> SELECT LAST_INSERT_ID();
LAST_INSERT_ID
----------------
NULL
-- now insert another row ...
sbx=> INSERT INTO id1 (num) VALUES(3);
OUTPUT
--------
1
sbx=> SELECT LAST_INSERT_ID();
LAST_INSERT_ID
----------------
750001
Now, back to Transaction 1:
sbx=> SELECT LAST_INSERT_ID();
LAST_INSERT_ID
----------------
500001
Still at the old value ...

SQLite returns int instead of real

I'm working on a website in node js and use SQLite as a database for the first time.
I want to be able to use real for some form data and I noticed that every real in my database are converted to integer once the query is made.
To vizualize the database i am using DB Browser and i checked if the columns are defined as REAL which they are.
If i try to query a data set as 0.1 in my DB I get this :
sqlite> select step_variable
from variables
where id=38;
0.0
After trying as suggested the command TYPEOF(step_variable) it returned :
0.0|real
In the SQLite CREATE TABLE command, one defines a data type affinity, not a data type. SQLite supports the following five column affinities: TEXT, NUMERIC, INTEGER, REAL, NONE.
Thus the data type you specify when creating a table does not enforce a certain data type. You can supply any data type you want or even omit the data type.
CREATE TABLE table1(
column1 ABC,
column2 Others,
column3 WHATEVER);
CREATE TABLE table2(column1, column2, column3);
Populate tables:
INSERT INTO table1 VALUES( 1, 'my text', 123.45);
INSERT INTO table2 VALUES( 1, 'my text', 123.45);
Now let us check what SQLite made out of it:
SELECT column1, TYPEOF(column1) from table1
SELECT column2, TYPEOF(column1) from table1
SELECT column3, TYPEOF(column1) from table1
With:
column TYPEOF(column)
------------------------
1 INTEGER
my text TEXT
123.45 REAL
When you go through a query result e.g. by using sqlite2_step you can use the sqlite3_column_type statement to confirm the column type - unless you know the result anyway and simply cast the result to the data type expected.
Martin
I found the solution it was simply that i didn't save my file after modifying it.

Cassandra Range queries on Map values using timestamp

I have below Cassandra table.
create table person(
id int PRIMARY KEY,
name text,
imp_dates map<text,timestamp>
);
Data inserted as below
insert into person(id,name,imp_dates) values(1,'one',{'birth':'1982-04-01','marriage':'2018-04-01'});
insert into person(id,name,imp_dates) values(2,'two',{'birth':'1980-04-01','marriage':'2010-04-01'});
insert into person(id,name,imp_dates) values(3,'three',{'birth':'1980-04-01','graduation':'2012-04-01'});
id | name | imp_dates
----+-------+-----------------------------------------------------------------------------------------------
1 | one | {'birth': '1982-03-31 18:30:00.000000+0000', 'marriage': '2018-03-31 18:30:00.000000+0000'}
2 | two | {'birth': '1980-03-31 18:30:00.000000+0000', 'marriage': '2010-03-31 18:30:00.000000+0000'}
3 | three | {'birth': '1980-03-31 18:30:00.000000+0000', 'graduation': '2012-03-31 18:30:00.000000+0000'}
I have requirement to write query as below. This required range on map value column.
select id,name,imp_dates from person where id =1 and imp_dates['birth'] < '2000-04-01';
I get following error
Error from server: code=2200 [Invalid query] message="Only EQ relations are supported on map entries"
The possible solution I can think of is:
1) Make map flat into multiple columns and then make it part of primary key. this will work but its not flexible since I may have to alter the schema
2) I can create another table person_id_by_important_dates to replace Map but then I loose read consistency as I have to read from two tables and join myself.
I do not wish to include imp_dates (map) part of primary key as it will create new row every time I insert with new values.
Appreciate help with this.
Thanks

Cassandra migrate int to bigint

What would be the easiest way to migrate an int to a bigint in Cassandra? I thought of creating a new column of type bigint and then running a script to basically set the value of that column = the value of the int column for all rows, and then dropping the original column and renaming the new column. However, I'd like to know if someone has a better alternative, because this approach just doesn't sit quite right with me.
You could ALTER your table and change your int column to a varint type. Check the documentation about ALTER TABLE, and the data types compatibility matrix.
The only other alternative is what you said: add a new column and populate it row by row. Dropping the first column can be entirely optional: if you don't assign values when performing insert everything will stay as it is, and new records won't consume space.
You can ALTER your table to store bigint in cassandra with varint. See the example-
cassandra#cqlsh:demo> CREATE TABLE int_test (id int, name text, primary key(id));
cassandra#cqlsh:demo> SELECT * FROM int_test;
id | name
----+------
(0 rows)
cassandra#cqlsh:demo> INSERT INTO int_test (id, name) VALUES ( 215478936541111, 'abc');
cassandra#cqlsh:demo> SELECT * FROM int_test ;
id | name
---------------------+---------
215478936541111 | abc
(1 rows)
cassandra#cqlsh:demo> ALTER TABLE demo.int_test ALTER id TYPE varint;
cassandra#cqlsh:demo> INSERT INTO int_test (id, name) VALUES ( 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, 'abcd');
cassandra#cqlsh:demo> SELECT * FROM int_test ;
id | name
------------------------------------------------------------------------------------------------------------------------------+---------
215478936541111 | abc
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 | abcd
(2 rows)
cassandra#cqlsh:demo>

Resources