Fork me on GitHub
#datomic
<
2018-05-28
>
drewverlee03:05:53

Whats the idiomatic way to use a previous value as the argument to the next value? Say i want to update all the people with name “drew” to “drew rocks” or “drew” + “something” 6 :person/name “drew rocks” evening 6 :person/name “drew” morning

drewverlee03:05:45

i can query for the entity id and name then use those in a transact.

val_waeselynck08:05:54

@U0DJ4T5U1 I assume the challenge here is to do it without race conditions? In that case, the way to go is to use a transaction function (https://docs.datomic.com/on-prem/database-functions.html), e.g [[:myapp/replace-first-name "drew" "drew rocks"]].

val_waeselynck08:05:02

If you're using Datofu (https://github.com/vvvvalvalval/datofu#writing-migrations-in-datalog), you can use the more general :datofu.utils/datalog-add transaction function, which acts as a Datalog interpreter, so that you don't have to create and install a custom transaction function. E.g:

[[:datofu.utils/datalog-add
  '[:find ?e ?a ?new-name :in $ ?old-name ?new-name :where
    [(ground :user/first-name) ?a]
    [?e ?a ?old-name]]
  ["drew" "drew rocks"]]]

ttx07:05:13

What is the justification for reverse reference of multi-arity "component" attributes returning only a single value in a datomic pull? Is there any way to return all the values? Relevant doc: https://docs.datomic.com/on-prem/pull.html#multiple-results

favila12:05:03

The justification is that a component attr should always be the only way to reach its entity value

favila12:05:35

Otherwise it’s not truly a component

souenzzo02:05:41

@U4XHJ3J9H you can do this

(let [db (d/db conn)
      {:keys [db-after]} (->> (d/q '[:find ?op ?e ?a ?v
                                     :where
                                     [(ground :db/retract) ?op]
                                     [(ground :db/isComponent) ?a]
                                     [?e :db/isComponent ?v]] db)
                              (vec)
                              (d/with db))]
  (d/pull db-after [:your/_pattern] eid))

ttx06:05:23

@U2J4FRT2T Not sure about what is being achieved by the code snippet. Can you please explain it to me?

favila07:05:00

This removes all isComponent annotations, writes it to a local (I.e. forked) db, then pulls from that db

👍 1
favila07:05:58

In essence, temporarily un-isComponent-ing all attributes so a reverse pull will always be cardinality many

misha20:05:51

datomic ♥️

misha20:05:58

Is there an idiomatic way to not do the transaction if key-value did not change? now it does not duplicate fact assertion, but still generates a transaction datom. It sounds like a tiny optimization, but, for example, for .csv file imports, if I want to have more granular error reports, I would not be able to put all the lines into a single transaction, I'd need to batch them. But that would "waste" 1 datom per batch even if batch changed nothing in DB. Smaller the batches – higher the chance of wasting precious datoms on repetitive (large) files imports. Especially, if I will put some meta info about file import in tx.

misha20:05:40

does :db/noHistory reduce datoms count over time, or somehow just reduces space, and that's it?

misha20:05:06

is it backed up by excision under the hood?

sparkofreason20:05:14

Has anybody successfully accessed Datomic Cloud across peered VPCs? Our app uses another service that requires VPC peering, and the same procedures do not work when applied to Datomic.

hcarvalhoaves20:05:17

@misha maybe you can avoid the empty transaction altogether w/ a transaction function by running a query on the transactor - that could negatively impact your transactor though, possibly more than just having the empty tx

misha21:05:55

@hcarvalhoaves yeah, thought about that, and would need to evaluate incoming files frequency vs amount of empty tx-datoms generated. However, transactions would contain fairly large nested maps, and comparing those with db data inside a transaction would likely be slower than I'd like it to be.

misha21:05:17

on the other hand, looking at error types which make tx fail, those are either network or dev errors: connection reset/timeout, and invalid value type. Which means, with enough testing, ETL step can collect batch of valid tx data from ~1k rows for a single transaction.

misha21:05:54

speaking of errors. I'd be delighted to see actual value, attribute and it's type in ExceptionInfo data map:

datomic.impl.Exceptions$IllegalArgumentExceptionInfo: :db.error/wrong-type-for-attribute Value 1 is not a valid :bool for attribute :foo/bar?
    data: #:db{:error :db.error/wrong-type-for-attribute}
From the error above you cannot tell that 1 was in fact string "1".

Peter Wilkins22:05:20

Hi all, just learning Datomic. Having a lot of fun. However have hits 2 queries I need a bit of help with: 1: get name and id for topics not in category

(defn orphaned-topics [conn]
  (d/q {:query '[:find [(pull ?topics [:topic/name :topic/id]) ...]
                 :in $ ?taxonomy
                 :where [?t]
                 [?tax :taxonomy/id ?taxonomy]
                 [?tax :taxonomy/categories ?cats]
                 (not [?cats :category/topics ?t])]
        :args  [(d/db conn) "z5ojxcs40azi"]}))
Error message is “Only find-rel elements are allowed in client find-spec”. I don’t understand what a find-rel is. 2: full text search returns a 500 server error after a long delay
(defn search-keywords [conn query]
  (d/q {:query '[:find ?entity ?name ?tx ?score
                 :in $ ?search
                 :where [(fulltext $ :keyword/phrase ?search) [[?entity ?name ?tx ?score]]]]
        :args  [(d/db conn) query]}))
CompilerException clojure.lang.ExceptionInfo: Server Error {:datomic.client-spi/request-id “f90939d2-b6f2-4c55-a8e3-18af3fa7e0b5", :cognitect.anomalies/category :cognitect.anomalies/fault, :cognitect.anomalies/message “Server Error”, :dbs [{:database-id “0ed6aab0-5e31-400f-8fd7-dc40dc67df98", :t 11, :next-t 12, :history false}]} Relevent schema:
#:db{:ident :category/id, :valueType :db.type/string, :cardinality :db.cardinality/one :unique :db.unique/identity}
      #:db{:ident :category/name, :valueType :db.type/string, :cardinality :db.cardinality/one}
      #:db{:ident :category/topics, :valueType :db.type/ref, :cardinality :db.cardinality/many}
      #:db{:ident :category/weight, :valueType :db.type/float, :cardinality :db.cardinality/one}
      #:db{:ident :keyword/excludes, :valueType :db.type/string, :cardinality :db.cardinality/many, :fulltext true}
      #:db{:ident :keyword/phrase, :valueType :db.type/string, :cardinality :db.cardinality/one, :fulltext true}
      #:db{:ident :taxonomy/categories, :valueType :db.type/ref, :cardinality :db.cardinality/many, :isComponent true}
      #:db{:ident :taxonomy/editable, :valueType :db.type/boolean, :cardinality :db.cardinality/one}
      #:db{:ident :taxonomy/id, :valueType :db.type/string, :cardinality :db.cardinality/one :unique :db.unique/identity}
      #:db{:ident :taxonomy/name, :valueType :db.type/string, :cardinality :db.cardinality/one}
      #:db{:ident :taxonomy/organization, :valueType :db.type/ref, :cardinality :db.cardinality/one}
      #:db{:ident :taxonomy-input/categories, :valueType :db.type/ref, :cardinality :db.cardinality/many}
      #:db{:ident :taxonomy-input/name, :valueType :db.type/string, :cardinality :db.cardinality/one}
      #:db{:ident :topic/document-count, :valueType :db.type/long, :cardinality :db.cardinality/one}
      #:db{:ident :topic/id, :valueType :db.type/string, :cardinality :db.cardinality/one, :unique :db.unique/identity }
      #:db{:ident :topic/keywords, :valueType :db.type/ref, :cardinality :db.cardinality/many, :isComponent true}
      #:db{:ident :topic/name, :valueType :db.type/string, :cardinality :db.cardinality/one, :fulltext true}
      #:db{:ident :topic/type, :valueType :db.type/ref, :cardinality :db.cardinality/one}
      #:db{:ident :topic-type/company}
      #:db{:ident :topic-type/risk}
Thanks for reading!

souenzzo02:05:08

1- pass db, not conn to your functions. db is immutable 2- pull ?topics but mathing :category/topics ?t 3- not sure if fulltext is avaible at datomic cloud