Fork me on GitHub
#xtdb
<
2023-10-14
>
Chris Lester02:10:02

Is it possible to include a var defined created in the where clause in a pull expression? I.e.,

(q '{:find [(pull e [:movie/year create-time]])]
     :where [[(get-create-time $ e) create-time]
             [e :movie/year 1987]]})

refset14:10:15

Hi Chris, unfortunately pull doesn't allow you to compose like that based on multiple inputs, it is really only capable of traversing from a single input starting entity

refset14:10:12

You could however return [create-time (pull e [:movie/year]])] use an outer query to assoc the create-time time into the map (assuming you are keen to push as much into the Datalog as possible)

Chris Lester20:10:21

I'd need to post process the results otherwise .. which would you recommend?

Chris Lester20:10:58

Alternatively I could just keep the timestamp on create/update as part of my app code and not use the history query capabilities. Seems more straightforward if less accurate (+ maintenance).

refset12:10:04

to clarify, I mean something like (haven't tested):

(q '{:find [m]
     :where [[(q {:find [create-time (pull e [:movie/year]])]
                  :where [[(get-create-time $ e) create-time]
                          [e :movie/year 1987]]}) [[ct e]]]
             [[(assoc e :create-time ct) m]]})

refset12:10:20

If you can make that work then I would recommend that, although I appreciate a deeply nested pull would be complex to make work if you need to the create-time from every level of entity...

Martynas Maciulevičius10:10:18

What I do is [(pull users [:user/name]) (pull posts [:post/text])] This produces a tuple-list of maps where I know the order. Now I want to produce one fat map for each result "row". And to do it I do this:

(->> (q {})
     (map (fn [[user post]]
            ;; if you pull :xt/id of both it's best to put the user as last item (if you want user's id) in the merge as the last argument will override the ID to its own. In this case "post" ID would win:
            (merge user post))))
And then you'll end up with:
[{:user/name "john"
  :post/text "I like trains!"}]