Fork me on GitHub
Akshay C. Gollapalli01:03:47

I think this might be a tick issue instead of a crux issue, but I can't seem to get this query to work properly: (crux/q (crux/db db) '{:find [e time] :where [[e :log/time time] [(tick/<= time (tick/- (tick/now) (tick/new-duration 2 :minutes)))]]}) Error: class clojure.lang.PersistentList cannot be cast to class java.time.Instant Does Crux treat things like "time" in the query above as lists before running them through predicates? Or is there something simple I missed? Document being queried: {:crux.db/id :demo-app/log, :log/event "app-stopped-successfully", :log/time #time/instant "2020-03-22T01:03:41.569599Z", :log/frequency #time/duration "PT1H"}


Hi @US65YEL1M it looks like you're trying to use Clojure directly inside of Crux Datalog, which isn't supported in the way you're trying to do here. Basically, you need to create a separate predicate function which you can then reference using a fully qualified name - see this issue which has a couple of examples that will help:

Akshay C. Gollapalli02:03:53

Thanks, defining my function (f) elsewhere and then using syntax quoting did the trick. (crux/q (crux/db db) {:find '[e time] :where ['[e :log/time time] [(f ~'time)]]})`

Akshay C. Gollapalli01:03:47

Doing things this way seems a bit off to me. The best way would probably be closer to just using the :crux.db/valid-time instead of the :log/time, is that accessible via datalog queries? I'm interested in entries that are older than a certain point, but it seems like using a snapshot gives only things that are newer than a certain point, or were valid at that point. How does one get items that were made valid within a certain range of time?


Hmm, I suspect using tick is most likely the correct approach for you actually. You can't access valid-time within queries by design, as that opens up a lot of complexity (though we are thinking hard about how to enable temporal range queries!). Therefore, for now, you should probably model your domain time as a regular attribute.

Akshay C. Gollapalli02:03:21

I ended up realizing that the crux valid time is the state of your data at that point. And realized that for what I was trying to do (create a monitoring app), the best thing was actually to create a document for the log, showing the current state for my application and then another document for the alert, which would become valid at a later point in time without intervention, telling me it's been too long since the app called in. Because that alert might be valid in the future, but isn't now, because it hasn't been long enough. Now my documents look like this: {:crux.db/id :demo-app/log, :log/event "app-start", :log/time #time/instant "2020-03-23T02:08:30.161563Z", :app/name :demo-app, :app/await :demo-app/await, :await/next-event #time/instant "2020-03-23T02:09:30.161555Z"} {:crux.db/id :demo-app/await, :app/name :demo-app, :await/timestamp #time/instant "2020-03-23T02:08:30.161555Z"} And my query like this: (crux/q (crux/db db) '{:find [app timestamp status next-event] :where [[e :app/name app] [e :log/event status] [e :await/next-event next-event] [e :app/await await] [await :await/timestamp timestamp]]

Akshay C. Gollapalli03:03:54

Thank you for the help!