我有一个由问题组成的领域模型,每个问题都与许多评论和肯定相关联。
我想做一个数据查询,它为每个问题提取一组内容属性,以及关联的注释和断言的数量,包括当这些关系是空的(例如,一些问题没有注释或没有肯定),在这种情况下返回的计数应该是0。
我看到了下面的要旨,它展示了如何使用(sum ...)和(or-join)与“权重”变量相结合,在关系为空时获得零计数。
然而,当有两个关系时,我不知道如何使这个工作。我尝试了以下方法,但返回的计数不正确:
(def query '[:find (sum ?comment-weight) (sum ?affirmation-weight) ?text ?time ?source-identifier ?q
:with ?uniqueness
:where
[?q :question/text ?text]
[?q :question/time ?time]
[?q :question/source-identifier ?source-identifier]
(or-join [?q ?uniqueness ?comment-weight ?affirmation-weight]
(and [?comment :comment/question ?q]
[?affirmation :affirmation/question ?q]
['((identity ?comment) (identity ?affirmation)) ?uniqueness]
[(ground 1) ?comment-weight]
[(ground 1) ?affirmation-weight])
(and [?comment :comment/question ?q]
[(identity ?comment) ?uniqueness]
[(ground 1) ?comment-weight]
[(ground 0) ?affirmation-weight])
(and [?affirmation :affirmation/question ?q]
[(identity ?affirmation) ?uniqueness]
[(ground 1) ?affirmation-weight]
[(ground 0) ?comment-weight])
(and [(identity ?q) ?uniqueness]
[(ground 0) ?comment-weight]
[(ground 0) ?affirmation-weight]))])最初被问到克洛朱里亚斯拉克。
发布于 2017-11-21 15:47:58
因此,总而言之,诀窍是将每个问题、注释和确认作为一个“数据点”来考虑,它对每个计数的“权重”为0或1,并且是唯一标识的(以便Datalog计数正确,请参阅:with)。特别是,每个问题对所有计数都有一个零权重。
发布的代码几乎是正确的,它只需要删除(or-join ...)的第一个子句,这将导致创建“人工”数据点(注释+肯定元组),从而污染计数。
下列措施应能发挥作用:
[:find (sum ?comment-weight) (sum ?affirmation-weight) ?text ?time ?source-identifier ?q
:with ?uniqueness
:where
[?q :question/text ?text]
[?q :question/time ?time]
[?q :question/source-identifier ?source-identifier]
(or-join [?q ?uniqueness ?comment-weight ?affirmation-weight]
(and
[?comment :comment/question ?q]
[(identity ?comment) ?uniqueness]
[(ground 1) ?comment-weight]
[(ground 0) ?affirmation-weight])
(and
[?affirmation :affirmation/question ?q]
[(identity ?affirmation) ?uniqueness]
[(ground 1) ?affirmation-weight]
[(ground 0) ?comment-weight])
(and
[(identity ?q) ?uniqueness]
[(ground 0) ?comment-weight]
[(ground 0) ?affirmation-weight]))]发布于 2017-11-21 16:11:51
您可以在查询中调用任意函数,因此可以考虑直接使用datomic.api/datoms (或子查询,或自己的任意函数)来计算注释和断言。
使用datomic.api/datoms
'[:find ?comment-count ?affirmation-count ?text ?time ?source-identifier ?q
:where
[?q :question/text ?text]
[?q :question/time ?time]
[?q :question/source-identifier ?source-identifier]
[(datomic.api/datoms $ :vaet ?q :comment/question) ?comments]
[(count ?comments) ?comment-count]
[(datomic.api/datoms $ :vaet ?q :affirmation/question) ?affirmations]
[(count ?affirmations) ?affirmation-count]]或者使用子查询:
'[:find ?comment-count ?affirmation-count ?text ?time ?source-identifier ?q
:where
[?q :question/text ?text]
[?q :question/time ?time]
[?q :question/source-identifier ?source-identifier]
[(datomic.api/q [:find (count ?comment) .
:in $ ?q
:where [?comment :comment/question ?q]]
$ ?q) ?comment-count-or-nil]
[(clojure.core/or ?comment-count-or-nil 0) ?comment-count]
[(datomic.api/q [:find (count ?affirmation) .
:in $ ?q
:where [?affirmation :affirmation/question ?q]]
$ ?q) ?affirmation-count-or-nil]
[(clojure.core/or ?affirmation-count-or-nil 0) ?affirmation-count]]或者使用自定义函数:
(defn count-for-question [db question kind]
(let [dseq (case kind
:comments (d/datoms db :vaet question :comment/question)
:affirmations (d/datoms db :vaet question :affirmation/question))]
(reduce (fn [x _] (inc x)) 0 dseq)))
'[:find ?comment-count ?affirmation-count ?text ?time ?source-identifier ?q
:where
[?q :question/text ?text]
[?q :question/time ?time]
[?q :question/source-identifier ?source-identifier]
[(user/count-for-question $ ?q :comments) ?comment-count]
[(user/count-for-question $ ?q :affirmations) ?affirmation-count]]https://stackoverflow.com/questions/47417009
复制相似问题