2014-01-13 34 views
6

如果我有以下Datomic數據庫:查找實體與Datomic缺少的屬性

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

如何查詢兩個實體(:fred:sally),找回了:fred屬性:likes :pizza和空值:sally

查詢

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

只返回:fred 42 :pizza

回答

12

Datomic最近已更新了Datomic查詢中可用的一些表達式函數。其中一個函數叫做get-else,如果一個實體上不存在某個屬性,它可以讓你提供一個默認返回值,就像clojure.core/get如果找不到密鑰就會返回一個選項第三個參數。

因此,使用你自己的例子,你只需要改變它,像這樣:

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

不幸的是你不能真正使nil「默認」值,因爲它不是一個有效的Datomic數據類型,如果你嘗試的話,Datomic會鯉魚,但是虛假應該會讓你去你想去的地方。

6

取回可能具有或可能不具有特定屬性的實體集合類似於關係數據庫中的LEFT JOIN。

datomic中的方法是執行兩個步驟:首先查詢實體,然後從那裏導航以獲取屬性值或nil如果屬性未針對給定實體聲明。

查看郵件列表帖子How do you do a left join in Datomic?及其附帶的gist爲例。

+2

其實,我相信'GET-else'在這種情況下,正確的做法。這是一個單一的查詢而不是兩個步驟。作爲參考,另一個類似的功能是「缺少?」。 – Psyllo