我目前正在评估 Datomic 用于存储和查询构成本体的已解析符号的用例。数据库中总共有 225122 个符号(实体)(所以它是一个相当大的本体,但对于数据库来说应该没什么大不了的)。
结构很标准,符号有
- 包含它们的父符号(如子符号等)
- 超级符号(它们继承的符号)
为了更好地访问符号,我们name
为每个符号设置了一个唯一的。这增加了以下 Datomic 模式:
[{:db/ident :ml/name,
:db/valueType :db.type/string,
:db/cardinality :db.cardinality/one,
:db/unique :db.unique/identity}
{:db/ident :ml/parent,
:db/valueType :db.type/ref,
:db/index true,
:db/cardinality :db.cardinality/one}
{:db/ident :ml/superclass,
:db/valueType :db.type/ref,
:db/index true,
:db/cardinality :db.cardinality/one}]
现在我有了最基本的递归查询“给我所有(传递地)包含在符号中的符号p
”。在原子术语中:
(def rules
'[
[(ubersymbol ?c ?p) (?c :ml/parent ?p)]
[(ubersymbol ?c ?p) (?c :ml/parent ?c1) (ubersymbol ?c1 ?p) ]
])
(q '[:find ?c ?n :in $ % :where
(ubersymbol ?c ?d) [?d :ml/name "name of a root symbol"] [?c :ml/name ?n]]
current-db rules)
查询本身(因此是一个中等大小的符号)需要5到5.5秒并返回 80 个命中。不是毫秒,而是真正的秒。这只是我想询问的关于数据集的最基本查询(它旨在从网络工具中使用,以帮助建模者理解本体的结构)。
我正在运行datomic-pro-0.9.5554
,使用内存数据库并使用对等库(我按照“入门”指南中的说明启动了服务器。
非常感谢帮助为 Datomic 提供案例。
马库斯