Cassandra.Ecto v0.5.1 Cassandra.Ecto.Adapter
Implements Ecto.Adapter
behaviour.
Queries
Cassandra repo supports only following keywords for Ecto.Query.from/2
:
:where
:order_by
:limit
:select
:preload
NOTE: don’t try to find
:offset
. It’s not supported by Cassandra.
NOTE: you should remember that by default in Cassandra it is not possible to filter and order by non primary key columns. To override this behaviour you could pass additional option
allow_filtering: true
. But it is not recommended, because of strong performance penalty. So it is very common to add extra tables that better fits specific queries, also you are free to create additional seconary indexes.Repo.all((from p in Post, where: "abra" in p.tags), allow_filtering: true)
Upserts and Lightweight transactions
By default in Apache Cassandra insert
and update
both are equivalent to upsert
.
But Ecto
by default expects that if record already exists it will raise error
on insert and it should not create new record on update.
So when Cassandra.Ecto
executes insert
it makes it conditional with
IF NOT EXISTS
and when executes update
- IF EXISTS
.
To perform upsert
with insert
just use option on_conflict: :nothing
.
To perform upsert
with update
just use option if: nil
.
If you wish to perform upserts by default you need to specify upsert: true
option in you repo. It might be very usefull for CQL version prior 3.2.
By the way, you can set :if
option for your update
and insert
queries.
Here is available types for :if
option:
:exists
:not_exists
[field1: value1, field2: value2, ...]
HINT: please take a look at last option with keyword list. You can use it for optimistic locking like so:
Repo.update!(post, if: [version: 2])
Comparision table
Ecto function :on_conflict :if Cassandra
------------- ------------ -- ---------
insert/2 :raise (no option) insert with 'IF NOT EXISTS'
insert/2 :nothing (no option) insert/upsert
insert/2 :nothing :not_exists insert with 'IF NOT EXISTS'
update/2 (no option) (no option) updates with 'IF EXISTS'
update/2 (no option) nil insert/upsert
update/2 (no option) :exists updates with 'IF EXISTS'
NOTE: this comparision table works only for repo without
upsert: true
option.
Batched queries
Batched queries are done by Ecto.Repo.insert_all/3
with option batched: true
.
By default all batched queries runs in :logged
mode. But it is possible to
override this on two levels:
Repo level, by setting
:batch_mode
repo optionconfig :my_app, Repo, adapter: Cassandra.Ecto batch_mode: :unlogged
Query level, by setting
:batch_mode
query optionRepo.insert_all(Post, posts, on_conflict: :nothing, batched: true, batch_mode: :unlogged)
Available types:
:logged
:unlogged
:serial
Default type is :logged
.
NOTE: don’t forget to set proper
:on_conflict
option.
Learn more about using batching in Using and misusing batches
Consistency
There are to options to configure consistency:
Tunable consistency.
Sets by
:consistency
option. Available types::any :one :two :three :quorum :all :local_quorum :each_quorum
Default type is
:one
.Linearizable consistency.
Sets by
:serial_consistency
option. Available types::serial :local_serial
Default type is
:undefined
.
Every type of consistency can be set at repo and query level deparately.
Please see Consistency for more information.
TIMESTAMP and TTL
You can specify TTL and TIMESTAMP with :ttl
and :timestamp
respectively
on query level.
:binary_id
autogeneration
By default Cassandra adapter generates :binary_id
with Ecto.UUID.bingenerate()
.
But it is also possible to override this behaviour and generate id natively
on Cassandra side with build-in functions now()
or uuid()
like so:
post = Repo.insert!(post, binary_id: :now)
If you have decided to make it default for repo:
config :my_app, Repo,
keyspace: "my_keyspace"
binary_id: :now
Possible option variants:
:now
:uuid
:default
Transactions
CASSANDRA DOESN’T SUPPORT TRANSACTIONS!