Fork me on GitHub
#datomic
<
2018-10-27
>
Logan Powell13:10:15

đź‘‹ Hi everyone, I'm trying to find some resources on normalizing nested data structures for designing/loading data into Datomic... I'm a little confused about how to represent ordered collections like PersistentArrayMap or vectors. Any pointers?

Logan Powell13:10:02

I'm currently thinking of batch loading (maybe with doseq) one transaction at a time using time as a way to order the values, but that seems complected

eoliphant15:10:16

Hi @loganpowell say attributes with many cardinality don't maintain any concept of ordering. If you need this, you'd need provide additional attributes (`:next` refs for lists, :index or something for arrays) to capture that in the db. There are a couple libs that address some of this that might be helpful directly or give you some ideas https://github.com/vvvvalvalval/datofu#implementing-ordered-to-many-relationships-with-an-array-data-structure, https://github.com/dwhjames/datomic-linklist

đź‘Ť 4
Logan Powell15:10:51

Thank you @eoliphant! I also saw this: https://github.com/pmbauer/datomizer I will definitely look into the libraries you've recommended!

4
đź‘Ť 4
schmee17:10:06

is there anything equivalent to Postgres UNNEST for cardinality many attributes?

schmee17:10:38

I have an entity that contains a cardinality many attribute required-tags, then I want to get all the tags in that array

schmee17:10:14

now I’m doing two queries, one to get the array, and one that takes the array as input to get the tags themselves

schmee17:10:24

but is there any way to do it with only one query?

favila18:10:04

Can you show an example of what you are doing? I don’t know the valuetype of required-tags or the structure of your entities, or precisely what you mean by the two queries

schmee18:10:41

;; What the list of tags looks like

user=>   (d/q '[:find  ?t .;
                :where [_ :file/required-tags ?t]]
              @db)
            
["tag1" "tag2" "tag3" "tag4"]

;; What I wish would work

user=>   (d/q '[:find  ?e
               :where [?e :tag/name ?t]
                      [_ :file/required-tags ?t]]
              @db)
#{}

;; What does work, but uses two queries

user=>   (d/q '[:find  [(pull ?e [*]) ...]
                :in $ [?names ...]
                :where [?e :tag/name ?names]]
           @db
           (d/q '[:find  ?t .
                  :where [_ :file/required-tags ?t]]
                @db)))
      
[<a bunch of data>]

favila20:10:14

What is it you want? What is “a bunch of data”?

favila20:10:09

I know you are doing some kind of join but I’m having trouble seeing what it is

favila20:10:47

I do t see that there is any difference between what you wish works and what does work

favila20:10:24

:tag/name and :file/required-tags are both string attrs?

favila20:10:45

You want entities with :tag/name values that are anywhere asserted as a :file/required-tags value?

schmee23:10:44

in the second query, the :where essentially translates to [?e :tag/name ["tag1" "tag2" "tag3" "tag4"]]

schmee23:10:51

What I’m after is to “unnest” the array into something like

(or [?e :tag/name "tag1"]
    [?e :tag/name "tag2"]
    [?e :tag/name "tag3"]
    [?e :tag/name "tag4"])

favila00:10:51

No that is incorrect that is not how catalog pattern matching clauses work

favila00:10:26

They match individual assertions (datoms)

favila00:10:31

Did you actually try your second query? Is that output from an actual repl?

idiomancy21:10:16

man. Cognitect really needs to partner with Salesforce. Everything that salesforce needs in order to accurately trend and analyze domain data is built into the core guarantees of datomic

steveb8n23:10:20

I work a lot with SFDC. Analytic snapshots do this as well. They don’t work for your requirements?

idiomancy21:10:40

that would skyrocket adoption