2017-11-21 3 views
0

私は質問で構成されたドメインモデルを持っています。各質問は多数のコメントと確認に関連しています。データ集計:ゼロカウントで結果を失うことなく関連するエンティティをカウントする

ノーコンテンツの束が各質問、ならびにこれらの関係は(例えば、いくつかの質問には一切コメントしていないか、または空の場合を含め、関連するコメントと断言数、属性抽出Datalog queryをしたいと思い肯定)、返されるカウントは、私は関係が空のときにゼロカウントを取得するために(sum ...)と「重量」変数と組み合わせ(or-join)を使用する方法を示しており、以下のGistを見てきました0

する必要があり、その場合、 。

ただし、2つの関係がある場合には、この作業を行う方法はわかりません。私は、次を試してみましたが、返された数が正しくありません:

(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]))]) 

はもともとClojuriansスラックに尋ねました。

答えて

0

要約すると、各質問、コメント、および肯定は、各カウントごとに0または1の「重み」を持つ「データポイント」とみなされ、一意に識別されます(Datalogがカウントする正しく、:withを参照してください)。特に、各質問はすべてのカウントに対してゼロの重みを持ちます。

投稿されたコードはほぼ正確で、(or-join ...)の最初の句を削除するだけで済み、その結果、カウントを汚染する「人工的な」データポイント(Comment + Affirmationタプル)が作成されます。

次は動作するはず

[: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]))] 
+0

この作品。ありがとうございました!私はまだそれが動作する理由について完全にはっきりしていません。私は、それぞれの最初の試合を返すという印象を受けていましたか?それとも、コメント/質問と肯定/疑問がある場合、コメントだけが数えられるのでしょうか?私はまだ私はgrokkingしていないと思う:仕事と – DizzyDez

+0

いいえ、または結合組合 - ブール値としてではないと思うまたは –

0

あなたは、クエリ内の任意の関数を呼び出すので、コメントをカウントするために、直接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]] 
+0

現在の固定のオーバーヘッド 'datomic.api/q'を考えると、私は慎重になるだろうサブクエリのアプローチ –

+0

datomic.api/datomsを使用しています:UnsupportedOperationExceptionこのタイプではカウントがサポートされていません:db $ datoms $ reify__2144 clojure.lang.RT.countFrom(RT.java:646) – DizzyDez

+0

このエラーは、 'datoms'がIterable、 'count'はサポートされていません。おそらく '(seq)'を使って強制することで対処するか、カスタム関数を使うことができます。 –

関連する問題