CI Test coverage(%) Code quality Stable version ScalaDoc Chat Open issues Average issue resolution time
Build Status Coverage Status Codacy Rating Maven Central ScalaDoc Gitter Percentage of issues still open Average time to resolve an issue

SASI Index support

Available as of phantom 2.11.0, SASI indexes introduce support for a Cassandra 3.4+ feature, namely SS Table attached secondary indexes. For more details on the internals of SASI within Cassandra, the details are here or here.

SASI was an attempt to improve performance on the more traditional secondary indexing, which is notoriously unreliabl performance wise after a couple thousand records.

Using SASI support in phantom.

SASI indexes are natively supported in the standard phantom-dsl module, so as long as you have the following in your build.sbt you will not require any special dependencies.

Maven Central

val phantomVersion = "__check_badge_above__"

libraryDependencies ++= Seq(
  "com.outworkers" %% "phantom-dsl" % phantomVersion

Then let’s start from a simple Cassandra connection:

import com.datastax.driver.core.SocketOptions
import com.outworkers.phantom.dsl._

object Connector {
  val default: CassandraConnection = ContactPoint.local
      new SocketOptions()
        replication eqs SimpleStrategy.replication_factor(1)

case class MultiSASIRecord(
  id: UUID,
  name: String,
  customers: Int,
  phoneNumber: String,
  set: Set[Int],
  list: List[String]

abstract class MultiSASITable extends Table[MultiSASITable, MultiSASIRecord] {
  object id extends UUIDColumn with PartitionKey

  object name extends StringColumn with SASIIndex[Mode.Contains] {
    override def analyzer: NonTokenizingAnalyzer[Mode.Contains] = {

  object customers extends IntColumn with SASIIndex[Mode.Sparse] {
    override def analyzer: Analyzer[Mode.Sparse] = Analyzer[Mode.Sparse]()

  object phoneNumber extends StringColumn with SASIIndex[Mode.Prefix] {
    override def analyzer: StandardAnalyzer[Mode.Prefix] = {

  object setCol extends SetColumn[Int]
  object listCol extends ListColumn[String]

class SASIDatabase(override val connector: CassandraConnection) extends Database[SASIDatabase](connector) {
  object multiSasiTable extends MultiSASITable with Connector

object db extends SASIDatabase(Connector.default)


SASI ships with 3 basic analyzers that are re-created in phantom.

The DefaultAnalyzer will allow you to set all the properties from the root, and the other two are nothing more than specialised forms.


Phantom SASI support incldues all three supported modes for SASI. All analyzers include support for basic comparison operations, as listed below. Some operators have two flavours, such as == and eqs, < and lt and so on. They are all available via the standard import com.outworkers.phantom.dsl._ import.

Operator Natural Language equivalent
== Equality operator
eqs Equality operator
< Strictly lower than operator
lt Strictly lower than operator
<= Lower than or equal to operator
lte Lower than or equal to operator
> Strictly greater than operator
gt Strictly greater than operator
>= Greater than or equal to operator
gte Greater than or equal to operator

There are two modes directed specifically at text columns, namely Mode.Prefix and Mode.Contains. By using these modes, you will be able to perform text specific queries using the like operator.


In addition to the standard operations, the Prefix mode will allow you to perform like(prefix("text")) style queries.

Examples can be found in SASIIntegrationTest.scala.

Example query, based on the schema defined above.

import com.outworkers.phantom.dsl._

trait PrefixExamples extends db.Connector { like prefix("example")).fetch()


This will enable further queries for text columns, such as like(suffix("value")) and like(contains("value))`, as well as prefix style queries.

Examples can be found in SASIIntegrationTest.scala.

Example possible queries, based on the schema defined above.

import com.outworkers.phantom.dsl._

val pre = "text"

trait ContainsExamples extends db.Connector { like prefix(pre)).fetch() like contains(pre)).fetch() like suffix(pre)).fetch()


As suggested in the official SASI tutorial, Mode.Sparse is directly targeted at numerical columns and it’s a way to enable standard operators for numerical columns that are not part of the primary key. All standard operators can be used.

Sparse mode SASI indexes cannot define analyzers, and automated schema creation will fail if you attempt to use an analyzer in Mode.Sparse

Examples can be found in SASIIntegrationTest.scala.

Example possible queries.

import com.outworkers.phantom.dsl._

trait SparseExamples extends db.Connector { eqs 50).fetch()

  // Select all entries with at least 50 customers >= 50).fetch()

  // Select all entries with at most 50 customers <= 50).fetch()