Open Time Store™
Copyright © JUXT LTD 2018-2019

Overview

There are four transaction (write) operations:

Table 1. Write Operations
Operation Purpose

crux.tx/put

Write a version of a document

crux.tx/cas

Compare and swap the version of a document, if that version is as expected

crux.tx/delete

Deletes the specific document at a given valid time

crux.tx/evict

Evicts a document entirely, including all historical versions

A document looks like this:

{:crux.db/id :dbpedia.resource/Pablo-Picasso
 :name "Pablo"
 :last-name "Picasso"}

In practice when using Crux, one calls crux.db/submit-tx with a sequence of transaction operations:

[[:crux.tx/put
 {:crux.db/id :dbpedia.resource/Pablo-Picasso
  :name "Pablo"
  :last-name "Picasso"}
 #inst "2018-05-18T09:20:27.966-00:00"]]

If the transaction contains CAS operations, all CAS operations must pass their pre-condition check or the entire transaction is aborted. This happens at the query node during indexing, and not when submitting the transaction.

For operations containing documents, the id and the document are hashed, and the operation and hash is submitted to the tx-topic in the event log. The document itself is submitted to the doc-topic, using its content hash as key. In Kafka, the doc-topic is compacted, which enables later deletion of documents.

Valid IDs

The following types of :crux.db/id are allowed:

  • Keyword (e.g. {:crux.db/id :my-id} or {:crux.db/id :dbpedia.resource/Pablo-Picasso})

  • UUID (e.g. {:crux.db/id #uuid "6f0232d0-f3f9-4020-a75f-17b067f41203"} or {:crux.db/id #crux/id "6f0232d0-f3f9-4020-a75f-17b067f41203"})

  • URI (e.g. {:crux.db/id #crux/id "mailto:crux@juxt.pro"})

  • URL (e.g. {:crux.db/id #crux/id "https://github.com/juxt/crux"}), including http, https, ftp and file protocols

The #crux/id reader literal will take any string and attempt to coerce it into a valid ID. Use of #crux/id with a valid ID type will also work (e.g. {:crux.db/id #crux/id :my-id}).

Put

Put’s a document into Crux. If a document already exists with the given :crux.db/id, a new version of this document will be created at the supplied valid time.

[:crux.tx/put
 {:crux.db/id :dbpedia.resource/Pablo-Picasso :first-name :Pablo} (1)
 #inst "2018-05-18T09:20:27.966-00:00"] (2)
  1. The document itself. Note that the ID must be included as part of the document.

  2. valid time

Note that valid time is optional and defaults to transaction time, which is taken from the Kafka log.

Crux currently writes into the past at a single point, so to overwrite several versions or a range in time, one is required to submit a transaction containing several operations.

CAS

The CAS operation (compare and swap) swaps an existing document version with a newer one, if the existing document is as expected.

[:crux.tx/cas
 {..} (1)
 {..} (2)
  #inst "2018-05-18T09:21:31.846-00:00"] (3)
  1. Expected Document

  2. New document

  3. valid time

Delete

Deletes a document at a given valid time. Historical version of the document will still be available.

[:crux.tx/delete :dbpedia.resource/Pablo-Picasso
#inst "2018-05-18T09:21:52.151-00:00"]

Evict

Evicts a document from Crux. The transaction history will be available, but all versions at or before the provided valid time are evicted.

[:crux.tx/evict :dbpedia.resource/Pablo-Picasso
#inst "2018-05-18T09:21:52.151-00:00"]

The evict transaction also supports additional parameters for straightforward eviction across time periods.

[:crux.tx/evict :dbpedia.resource/Pablo-Picasso
  #inst "2018-05-18T09:21:52.151-00:00" ; start-valid-time
  #inst "2018-05-19T09:21:52.151-00:00" ; end-valid-time
  true                                  ; keep-latest?
  false]                                ; keep-earliest?