I am trying to use the datastax java driver to update and query a column family that has a map field. Does anyone an example about how to use cql collections with the Datastax Java Driver?
Thanks
Normally I'd ask what you've tried, but I know that this isn't in the DataStax documentation for the Java Driver. I'll go through what worked for me.
A couple of things to note:
cqlsh
if you want to see what they are outside your app.To update an existing row (in the "users" table which has a Map<varchar,varchar> phone_numbers
), try something like this:
String cqlQuery = "UPDATE users SET phone_numbers = phone_numbers + ";
cqlQuery += "{'" + phoneType + "':'" + phoneNumber+ "'} ";
cqlQuery += "WHERE username = ?";
PreparedStatement preparedStatement = getSession().prepare(cqlQuery);
BoundStatement boundStatement = preparedStatement.bind(user);
getSession().execute(boundStatement);
The better way to do this (assuming a Map<String,String> phoneNumbers
), is to bind the collection to the prepared statement, like this:
String cqlQuery = "UPDATE users SET phone_numbers = ? ";
cqlQuery += "WHERE username = ?";
PreparedStatement preparedStatement = getSession().prepare(cqlQuery);
BoundStatement boundStatement = preparedStatement.bind(phoneNumbers,user);
getSession().execute(boundStatement);
Likewise, to read it back out:
String cqlQuery2 = "SELECT phone_numbers FROM users WHERE username = ?";
PreparedStatement preparedStatement2 = getSession().prepare(cqlQuery2);
BoundStatement boundStatement2 = preparedStatement2.bind(user);
ResultSet result2 = getSession().execute(boundStatement2);
Map<String,String> newMap = result2.one().getMap("phone_numbers", String.class, String.class);
They just covered this today in the (free) CAS101J class on DataStax Academy.
I will add some examples of using the CQL collections with both simple and prepared statements to the current Java driver doc.
You can use CQL collections with prepared statements. There's an example in the Java driver doc in the quick start section.
Step 4 binds a Java HashSet object to a CQL set column in the songs table.
Here is how I did it; This has mapping for a tuple column in Cassandra as well as the map column in Cassandra. I was using Scala with the DataStax Cassandra Java Driver
Needed imports
import java.lang
import java.text.SimpleDateFormat
import com.datastax.driver.core._
import com.datastax.driver.core.querybuilder.QueryBuilder
import scala.collection.Map
import org.apache.spark.SparkContext
import org.apache.spark.SparkConf
import com.datastax.spark.connector.cql.CassandraConnector
import org.apache.spark.rdd.RDD
import scala.collection.JavaConversions._
Code snippet
val simpleDateFormat: SimpleDateFormat = new SimpleDateFormat("dd-MM-yyyy H:mm:ss")
val start_date: java.util.Date = simpleDateFormat.parse(val("StartTime").replaceAll(":(\\s+)", ":"))
val b_tuple= session.getCluster().getMetadata().newTupleType(DataType.cint(), DataType.cint(), DataType.text())
val time_tuple = session.getCluster().getMetadata().newTupleType(DataType.timestamp(), DataType.timestamp())
val time_tuple_value = time_tuple.newValue(start_date, end_date)
val b_tuple_value = bin_cell_tuple.newValue(b._1: lang.Integer, b._2: lang.Integer, val("xxx"))
val statement_2: Statement = QueryBuilder.insertInto("keyspace", "table_name")
.value("b_key", bin_cell_tuple_value)
.value("time_key", time_tuple_value)
.value("some_map", mapAsJavaMap(my_scala_map))
session.executeAsync(statement_2)