Fork me on GitHub
#datomic
<
2020-06-14
>
craftybones13:06:33

Hello. Just about beginning to play with datomic. I have a specific need and I think datomic fits the bill, I was wondering if anyone could give me pointers. I need to build a dossier system of sorts where there are notes and other details maintained for several candidates. As this detail changes through time, it would help for us to have historic information visible about each candidate

craftybones13:06:46

In Mongo, this would be a series of records, timestamped, but all really containing mostly the same information

craftybones13:06:44

So given that I want to maintain a history and given that the schema can be flexible, Datomic sounds right, am I correct in assuming this?

craftybones14:06:07

so let us say, I make a series of assertions on :notes , then later on, I’d like to look at :notes, not just as what the latest is, but all the :notes accrued over time

craftybones14:06:19

This should be (trivially?) possible right?

val_waeselynck14:06:36

@U8VE0UBBR as a non-official source on Datomic, I advise against using Datomic's historical features for giving users access to revisions: https://vvvvalvalval.github.io/posts/2017-07-08-Datomic-this-is-not-the-history-youre-looking-for.html Datomic is not a bitemporal database. A priori, I recommend making one entity per note revision, as you would do with a regular database.

craftybones15:06:43

So you suggest an additional attribute that records the version as well, as opposed to relying just on timestamps

craftybones15:06:55

I see what you are saying here, history changes are fine as long as the shape remains the same

craftybones15:06:58

the second the shape changes

craftybones15:06:04

that becomes more complex

craftybones15:06:44

However, even with what you are saying, its easier to use datomic here isn’t it, given the use case?

val_waeselynck15:06:33

Datomic can be easier to use, for general reasons not related to modeling revisions, such as flexible schema, expressive reads and writes, ease of data sync, etc.

craftybones15:06:16

Alright. In this case, I have a very specific need of having to look at history

val_waeselynck15:06:41

You may be fine just storing one entity per revision or per change, if your queries aren't highly sophisticated.

val_waeselynck15:06:38

Otherwise might want to look at bitemporal dbs like Crux, but there are many other aspects to consider than historical query features.

craftybones15:06:25

As of now, I just want a history of notes per person let us say

craftybones15:06:41

so let us say some attribute was added only at tx 200, what is the cost to me as a developer if I query for that attribute in an earlier transaction?

val_waeselynck15:06:49

The main question for assessing Datomic against such use cases is how complicated your historical queries are

craftybones15:06:51

Pretty much no branching, straight ahead, give me everything you’ve got on person x, at most limited by a specific duration

craftybones15:06:19

Assuming incredibly low performance needs, never more than a handful of users at any point

craftybones15:06:00

From what I am reading of the schema change, I could potentially backfill necessary data, which might not even be necessary for certain types of attributes

favila12:06:45

Well you can’t backfill such that it looks as if it was transacted in the past. That is the limitation of relying on datomic history for revisions

favila12:06:35

Datomic history is more like (immutable, not branching) git history than like time-series records

Drew Verlee21:06:27

How does using a predicate directly in the query (https://docs.datomic.com/cloud/query/query-data-reference.html#predicates) compare to querying the data then performing the predicate? I assume the predicate runs somehow before the join?

Drew Verlee22:06:33

the answer is in the docs: > The predicates =, !=, <=, <, >, and >= are special, in that they take direct advantage of Datomic's AVET index. This makes them much more efficient than equivalent formulations using ordinary predicates. For example, the "artists whose name starts with 'Q'" query shown above is much more efficient than an equivalent version using starts-with?

Drew Verlee22:06:54

errr. wait < works on strings to compare the first two letters?

;; fast -- uses AVET index
[(<= "Q" ?name)]
[(< ?name "R")]

;; slower -- must consider every value of ?name
[(clojure.string/starts-with? ?name "Q")]
That seems really odd

Drew Verlee22:06:18

what does it mean "they take advantage of datomics AVET index" does that mean the comparison is done using information in the index as well? like when we say index im thinking "alice" "bob" "zack" so using the index in the context of (< ?name "d") would mean that zack is returned and the operation do this never actual had to look at the string zack because i was stored in location that was marked like "d-z" or something.

favila12:06:32

It means it can figure out the equivalent d/index-range call

favila12:06:02

(It’s not literally d/index-range but the semantics are the same)

favila12:06:55

If the query planner can see the attribute you are using, know it has an avet index, and see the comparisons and their values it can figure out a subset of the values in the index to seek instead of seeking the whole thing

Drew Verlee12:06:05

for 'on-prem' i understand you have to add an avet index for an attribute by doing a transaction. i did a search through my cloud db and i don't see a db/index attribute. Do i need to add avet indexs for the queries that use index e.g d/index-range to work? and if so, how?

favila13:06:04

cloud adds value indexes for everything already

Drew Verlee13:06:19

awesome, thanks!