Fork me on GitHub
#datomic
<
2015-08-02
>
lboliveira02:08:55

Hello! How do I get a max value and its entity id using the same query?

(d/q '[:find [(max ?a) ...]
       :where [?e :a ?a]]
     [[1 :a 10]
      [2 :a 20]
      [3 :a 30]])
=> [30]
Returns 30. ok.
(d/q '[:find [(max ?a) ?e]
       :where [?e :a ?a]]
     [[1 :a 10]
      [2 :a 20]
      [3 :a 30]])
=> [10 1]
Returns [10 1]. How do I write a query that returns [30 3]?

bhagany02:08:53

so… I can see what it's doing, but I'm not sure how to make it not do that

bhagany02:08:27

anytime you include a non-aggregate lvar in :find, it's going to group the aggregates by that lvar

bhagany02:08:49

I think I would just issue one query for (max ?a), and a second for ?e

bhagany02:08:05

I think that's the only way because there may be more than one ?e

bhagany02:08:25

heh, I should have tagged you - @lboliveira ^^

lboliveira03:08:21

@bhagany: Ty. So the idiomatic way to query the id is making two queries?

bhagany03:08:29

@lboliveira: in this case, I would say yes. In general, you don't need to worry about round tripping to the database with datomic like you do with other db's

bhagany03:08:10

I'm pretty positive that ?e is already going to be in local memory because of the first query

lboliveira03:08:49

@bhagany: I am wondering if I could have some issues if a new value is inserted between these calls.

bhagany03:08:14

@lboliveira: ah, this is another thing you don't need to worry about with datomic simple_smile

bhagany03:08:41

if you pass the same db value in to d/q, that is guaranteed not to happen; it's immutable

bhagany03:08:03

so you can be completely assured that you're getting a consistent view of your data

lboliveira03:08:51

you are soo right. It takes time to wrap the mind about it. 😃

lboliveira03:08:58

thank you soo much.

bhagany03:08:17

@lboliveira: my pleasure simple_smile it took me a bit to wrap my head around it too.

lboliveira03:08:33

and the "don't worry about round trips".

lboliveira03:08:57

it make all queries diferent

lboliveira03:08:31

It is very cool way to interact with the database.

bhagany03:08:11

yes, very! there's a great talk by Rich where he goes into detail about the benefits of the datomic operational model, and this one really struck me. It's just so nice not to have to grab all the data you might need up front

lboliveira03:08:04

https://github.com/Yuppiechef/datomic-schema

This is to arbitrarily support extra generating options, including the new index-all? option, which flags every attribute in the schema for indexing (in line with Stuart Halloway's recommendation that you simply turn indexing on for every attribute by default).
@bhagany: Do you have any thoughts about it?

bhagany03:08:46

@lboliveira: I haven't used it, but I have seen people refer positively to it here and on IRC.

lboliveira03:08:07

And about index all?

bhagany03:08:15

personally, I don't have a problem with the raw schema, and I kind of like having it there as data.

bhagany03:08:29

do you mean having :db/index true on all attributes?

lboliveira03:08:41

Yes. Do you do that?

bhagany03:08:04

oh, I missed your first message somehow. Yes, I do that, based on the same recommendation from Stu.

lboliveira03:08:52

This is a "wow" thing to me.

lboliveira03:08:44

I could not find the Halloway's recommendation. Do you have a link? I have some boolean attributes. It seems odd to index them.

bhagany03:08:22

I don't have a direct link, I saw it in one of the Day of Datomic videos

lboliveira03:08:54

{:db/error :db.error/incompatible-schema-install, :entity :ping.reply/start, :attribute :db/index, :was false, :requested true}
:ping.reply/start is a :db.type/instant

lboliveira03:08:25

I was trying to add an index to it

bhagany04:08:03

@lboliveira: hmm, I would guess you can't change the :db/index setting of an installed attribute?

bhagany04:08:51

this rings a bell, I bet it's partially why they started recommending that you index all attrs. It isn't too expensive, and much easier than adding it after the fact.

bhagany04:08:44

aha, did you do the :db/alter thing?

lboliveira04:08:37

\o/

#object[datomic.promise$settable_future$reify__6754 0x7227ddab {:status :ready, :val {:db-before datomic.db.Db@887b21a0, :db-after datomic.db.Db@d16e8b12, :tx-data [#datom[13194139669062 50 #inst "2015-08-02T04:12:53.505-00:00" 13194139669062 true] #datom[80 44 true 13194139669062 true] #datom[80 44 false 13194139669062 false] #datom[0 19 80 13194139669062 true]], :tempids {}}}]
@bhagany: Thank you again. 😃

bhagany04:08:48

alright! congrats

Ben Kamphaus19:08:17

@bhagany and @lboliveira one thing to note re: turning index on, is that this recommendation is meant for data models which stick pretty fairly close to Datomic’s modeling recommendations. We’ve found (since making the recommendation) that it collides with some common antipatterns in Datomic - e.g. storing large blobs/documents in string attributes.

bhagany19:08:58

@bkamphaus: thanks! good thing I'm not doing that simple_smile

Ben Kamphaus19:08:50

Cool. I don’t think most are doing that, but definitely a few have run into perf issues, index failures, etc. introduced by the combo of :avet + 10MB document-like string values.