2016-10-02 28 views
0

次のクエリを使用して2つのカウントの差を計算しようとしています。CYPHER - 異なるCOUNTが同じ結果を返します

MATCH (user: User {username : 'bar' }) 
MATCH (user)-[upvote : UPVOTED]->(:Post) 
MATCH (user)-[downvote : DOWNVOTED]->(:Post) 
RETURN COUNT(upvote) - COUNT(downvote) 

両方のカウントが同じ値であるため、それは常に0を返します。私はそれぞれのカウントごとに別々にクエリを実行しましたが、実際には異なっています(3と1)が、クエリでは無駄な結果が返されます。

私はこのクエリ

MATCH (user : User {username : 'bar' }) 
MATCH (user)-[upvote : UPVOTED]->(:Post) 
MATCH (user)-[downvote : DOWNVOTED]->(:Post) 
RETURN COUNT(downvote) 

を実行すると期待される出力がMATCH大きい結果を支配しているかのようにある1である[UPDATE]

が変なふうに、それは、3を返し

アイデアありがとう

+0

「COUNT」を追加する前に、そのクエリの結果を調べてみましたか?あなたはそれが実際に一致しているか知っていますか?それはなぜあなたにアイデアを与えるかもしれません。 – jonrsharpe

+0

私はマッチを別々にテストし、リストを返します。 upvotesのための3項目とdownvotesのための1項目。両方のマッチでクエリを実行すると、それぞれに3つのアイテムを持つ2つのリストが返されます。関係にはプロパティがないため、返されたアイテムの内容を確認することはできません。 –

+0

それぞれのカウントは何ですか? 4? – jonrsharpe

答えて

3

Neo4jは、MATCHとOPTIONAL MATCHESを実行するときに行を作成します。以前のクエリの結果の数に依存します。例えば

、のは、ユーザーが3 upvotedが、upvotesのためのあなたのMATCHの終わりに1

をdownvotedしていることを言わせて、構築された行の数は、ユーザとそれぞれ、3であり、各upvoted関係。

しかしdownvotesためMATCHの終わりに、構築された行の数は3です。各行にはあります。ユーザー、upvotesの一つであり、単一downvote:

user, up1, down1 
user, up2, down1 
user, up3, down1 

カウントのをアップは正確でなければなりませんが、ダウンの数は3となります。

これはパフォーマンス上のヒットであることに注意してください。ユーザーのダウンワードを取得するクエリは、単一のユーザーに対しては1回は実行しませんが、ユーザーがいる行ごとに3回各行で同じユーザーであることがあります)。

あなたは2つのdownvotes代わりの1を持っていた場合、その後、6つの構築行(3×2、それぞれの可能downvoteとペアにそれぞれupvote)があるでしょう:あなたがやった場合

user, up1, down1 
user, up1, down2 
user, up2, down1 
user, up2, down2 
user, up3, down1 
user, up3, down2 

DISTINCTアップのカウントそして、クエリの最後にDISTINCTダウンが、あなたは右の数字を取得する必要がありますが、より良い方法は、バックツーバックの一致に注意することである(ここで、複数の行の最初の試合の結果)と、このように初期の数を計算します:

MATCH (user : User {username : 'bar' }) 
MATCH (user)-[upvote : UPVOTED]->(:Post) 
WITH user, COUNT(upvote) as upvotes 
MATCH (user)-[downvote : DOWNVOTED]->(:Post) 
RETURN upvotes, COUNT(downvote) as downvotes 

この理由は、あなたはupvoteカウントで、1つのビルド行:ユーザーを持っています。我々はdownvotesに一致した場合、構築の行は、各downvoteの関係でカウントupvoteを持つユーザーになります。

user, 3 as upvotes, down1 
:あなたはCOUNT関数を実行するときに正確なカウントを取得しますdownvotes×1、数

1つではなく2つのダウンボトムがある場合は、

user, 3 as upvotes, down1 
user, 3 as upvotes, down2 

などとなります。

一般的には、バックツーバックマッチまたはオプションマッチの間で集計(カウント、収集など)を実行することができます(もちろん、あなたが何をしているのか、あなたの場合はバックツーバックのマッチが正しい)。 neo4jが行を構築している様子を視覚化すると、間違っているかもしれないことがわかります。

関連する問題