我希望能够做这样的事情:
(defn match? [m] (re-find (re-pattern "so (\\d+)") m))
(datomic.api/q
'[:find ?m
:where [[?e :user/regex-match ?r]
[(user/match? ?e) ?m]]
dbconn)
这给了我我所期望的,但它称为“匹配?”每个实体两次:
(datomic.api/q
'[:find ?m
:where [[?e :user/regex-match ?r]
[(user/match? ?e) ?m]
[(user/match? ?e)]
dbconn)
最佳答案
如果您担心性能,请使用:
(->> (d/datoms (d/db conn) :aevt :user/regex-match)
(filter #(user/match? (:v %)))
(map :v))
它使用 datomic.api/datoms用于流式传输与谓词匹配的 :user/regex-match
属性值的 API,即 user/match?
。这保证您的谓词函数仅执行一次(每个实体)。请注意,您可以将 (map :v)
替换为 (map :e)
来检索其实体 ID。
如果您真的担心性能并且愿意使用额外的内存来实现它,请使用:
(def fast-match? (memoize match?))
(->> (d/datoms (d/db conn) :aevt :user/regex-match)
(filter #(fast-match? (:v %)))
(map :v))
这会创建一个 memoized你的函数的版本。此版本具有更强的性能保证,因为您的谓词函数将最多运行一次(即每个不同值运行一次),并且如果您的属性值是有限集的一部分,它可以为您提供卓越的性能。
有关完整的代码示例,请参阅 https://gist.github.com/a2ndrade/5651065
关于regex - 数据原子查询 - 过滤和绑定(bind)的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16386793/