-
Notifications
You must be signed in to change notification settings - Fork 186
Collection columns
Cassandra collections do not allow custom data types. Storing JSON as a string is possible, but it's still a text
column as far as Cassandra is concerned. The type
in the below example is always a default C* type.
Examples on how to use JSON columns can be found in JsonColumnTest.scala
phantom columns | Cassandra columns |
---|---|
ListColumn.<type> | list<type> |
SetColumn.<type> | set<type> |
MapColumn.<type, type> | map<type, type> |
JsonColumn.<type> | text |
JsonListColumn.<type> | list<text> |
JsonSetColumn.<type> | set<type> |
JSON columns require you to define a toJson
and fromJson
method, telling phantom how to go from a String
to the type you need.
It makes no assumptions as to what library you are using, although we have tested with lift-json
and play-json
.
An example of a fully working Cassandra table using the whole variety of JSON columns can be found below. It's worth noting that before phantom 1.25.x, any collection column in phantom would need 3 arguments when being defined, which looked something like the below, where you needed to provide both the table type and the record type of the host table, as well as the type of the actual collection:
object listColumn extends ListColumn[TableClass, RecordClass, String](this)
In more recent versions of phantom, collection types consumed at DSL levels have been moved, so now they are type alises nested within Cassandra table. This means we can now the type of the host table and the record it holds without it needing to be provided explicitly.
import com.websudos.phantom.dsl._
import net.liftweb.json.{DefaultFormats, Extraction, JsonParser, compactRender}
case class JsonTest(prop1: String, prop2: String)
case class JsonClass(
id: UUID,
name: String,
json: JsonTest,
jsonList: List[JsonTest],
jsonSet: Set[JsonTest]
)
class JsonTable extends CassandraTable[ConcreteJsonTable, JsonClass] {
implicit val formats = DefaultFormats
object id extends UUIDColumn(this) with PartitionKey[UUID]
object name extends StringColumn(this)
object json extends JsonColumn[JsonTest](this) {
override def fromJson(obj: String): JsonTest = {
JsonParser.parse(obj).extract[JsonTest]
}
override def toJson(obj: JsonTest): String = {
compactRender(Extraction.decompose(obj))
}
}
object jsonList extends JsonListColumn[JsonTest](this) {
override def fromJson(obj: String): JsonTest = {
JsonParser.parse(obj).extract[JsonTest]
}
override def toJson(obj: JsonTest): String = {
compactRender(Extraction.decompose(obj))
}
}
object jsonSet extends JsonSetColumn[JsonTest](this) {
override def fromJson(obj: String): JsonTest = {
JsonParser.parse(obj).extract[JsonTest]
}
override def toJson(obj: JsonTest): String = {
compactRender(Extraction.decompose(obj))
}
}
def fromRow(row: Row): JsonClass = {
JsonClass(
id(row),
name(row),
json(row),
jsonList(row),
jsonSet(row)
)
}
}
abstract class ConcreteJsonTable extends JsonTable with RootConnector {
def store(sample: JsonClass): InsertQuery.Default[ConcreteJsonTable, JsonClass] = {
insert
.value(_.id, sample.id)
.value(_.name, sample.name)
.value(_.json, sample.json)
.value(_.jsonList, sample.jsonList)
.value(_.jsonSet, sample.jsonSet)
}
}
To stay up-to-date with our latest releases and news, follow us on Twitter: @outworkers.
- Issues and questions
- Adopters
- Roadmap
- Changelog
- Tutorials
- Commercial support
- Using phantom in your project
- Primitive columns
- Optional primitive columns
- Collection columns
- Collection operators
- Automated schema generation
- Indexing columns
- Data modeling with phantom
- Querying with phantom
- Asynchronous iterators
- Batch statements
- Apache Thrift integration
- Apache ZooKeeper integration
- The phantom testkit