質問

If I have the following Datomic database:

{ :fred :age 42 }
{ :fred :likes :pizza }
{ :sally :age 42 }

How do I query for both entities (:fred and :sally), getting back the attribute :likes :pizza for :fred and an empty value for :sally?

The query

[:find ?n ?a ?l
 :where [?n :age ?a]
        [?n :likes ?l]]

only returns :fred 42 :pizza.

役に立ちましたか?

解決

Datomic has recently been updated with a few expression functions available to you in Datomic queries. One of these functions is called get-else and it lets you provide a default return value if an attribute doesn't exist on an entity, much like how clojure.core/get will return an option third param if the key isn't found.

So using your own example, you would only need to change it like so:

[:find ?n ?a ?l :where [?n :age ?a] [(get-else $ ?n :likes false) ?l]

Unfortunately you can't actually make nil a "default" value since it's not a valid Datomic data type, and Datomic will carp if you try, but false should get you where you're going as well.

他のヒント

You can also try the "missing?" fn.

Have a look on this:

http://docs.datomic.com/query.html#missing

Getting back a set of entities which may or may not have particular attributes asserted is analogous to a LEFT JOIN in a relational database.

The approach in datomic is to do two steps: first query for the entities and then navigate from there to get the attribute values or nil if the attribute is not asserted for a given entity.

See the mailing list post How do you do a left join in Datomic? with its accompanying gist for an example.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top