2017-10-26 7 views
1

[OK]をので、ここで私のデータモデルです。各ユーザーは:ASSIGNED_TO、さらに:ASSIGNED_TOです。場所は:BELONGS_TOです。取得不正な値は

私はIDで特定のアカウントを選択しようとしており、そのアカウントのユーザーと場所の数も返します。ここに私のクエリは次のとおりです。

MATCH (account:Account) 
WHERE account.id = '123456' 
WITH account 
OPTIONAL MATCH (location:Location)-[:BELONGS_TO]->(account) 
OPTIONAL MATCH (user:User)-[:ASSIGNED_TO]->(account) 
RETURN account, count(location) as locationCount, count(user) as userCount 

結果は、userCount = 16 (correct)locationCount = 16 (incorrect; should be 1)accountです。私がdistinctを位置カウントに加えた場合は、count(distinct location)、正しい結果が得られます(1)。ユーザーのためにOPTIONAL MATCHを削除すると、ロケーションカウントも1になります。関係とアカウントとの関係がわかりましたが、私は別名のないクエリが機能しない理由を理解しようとしています。また、これを書く良い方法はありますか?

答えて

1

これは実際には少しトリッキーです。

MATCH (account:Account) 
WHERE account.id = '123456' 
MATCH (location:Location)-[:BELONGS_TO]->(account)<-[:ASSIGNED_TO]-(user:User) 
RETURN account, count (location), count (user) 

あり1つのアカウントが真ん中にありますが、あなたは数字がそれぞれの側にあるのか分からない:これは、あなたが探しているパターンを表示するように書き換えられたクエリです。 結果セットには、パターンのすべての一致が含まれます(16の場合もありますが、複数の場所に割り当てられたユーザーや場所が複数ある可能性があります)。だから実際にどちらも数は正しい(あなただけのユーザーのために幸運になる)。

MATCH (account:Account) 
WHERE account.id = '123456' 
MATCH (location:Location)-[:BELONGS_TO]->(account)<-[:ASSIGNED_TO]-(user:User) 
RETURN account, count (DISTINCT location), count (DISTINCT user) 

DISTINCTが問題を解決します。アカウントごとに集計されます(実際の集計は1つしかありません)。結果セットには16の場所があります。 DISTINCTでは、ユニークなものだけがカウントされます。そして、同じことがユーザーにもあてはまります!このことができます

MATCH (account:Account) 
WHERE account.id = '123456' 
MATCH (location:Location)-[:BELONGS_TO]->(account) 
RETURN account.id as id, "location count" as type, count(location) as ct 
UNION 
MATCH (account:Account) 
WHERE account.id = '123456' 
MATCH (account)<-[:ASSIGNED_TO]-(user:User) 
RETURN account.id as id, "user count" as type, count(user) as ct 

希望:

は違いを確認するには、このクエリを見てみましょう。

よろしく、 トム

+0

トム、返信ありがとうございます。私はそれが動的に生成されたため、私はそれが(ユーザーと場所のための別々の選択的なMATCHステートメント)として書かれたクエリを持っていた理由でした。私は 'withUsers'と 'withLocations'の引数を持っています。これは独立して設定できるので、最終クエリでどちらか一方または両方を持つことができます。私はその「別個の」作品を手に入れました。なぜなら、データベースに1つしかない場合、16の位置のカウントが返される理由を理解しようとしています。私はそれが16人のユーザーとの関係と関係があると思うが、なぜそれが当てはまるのか分からない。 – Jason

+0

これは、あなたのカウントを決定している(アカウントごとにグループ化された)完全なパターンの一致数であり、(!!!)ユーザーまたは場所ではありません。それは20ヒットを発見した場合、あなたのカウントは20だったでしょう。 –

0

グラフの代わりに結果を表示すると、実際には16行のデータがあることがわかります。各行にはlocationが含まれ、count(location)は実際にlocationの行数を返します。

重複を削除する場合は、distinctを使用することをおすすめします。我々は生産現場でサービスを提供しており、同様のシナリオでdistinctを使用しています。

0

私は同様の問題に直面していたし、それがRDBMSの観点から考えて助けました。

(私は例えば4を使用します)ので、のようなユーザーのテーブルを考えてみましょう:

Users 
----- 
u1 
u2 
u3 
u4 

そして、(あなたの場合のように、一つのレコードごとに)2つの場所のテーブルやアカウントごとを考えてみます。今

Locations 
--------- 
loc1 

Accounts 
-------- 
acc1 

、のNeo4jは MATCH (location:Location)-[:BELONGS_TO]->(account)<-[:ASSIGNED_TO]-(user:User)のようなクエリを評価するとき、それは Userノード、および Locationノードを探し始め、それがその後、結合を実行し Accountノードに内側の関係を次の。したがって、そのクエリを中間クエリに分解すると、 MATCH (location:Location)-[:BELONGS_TO]->(account)MATCH (account)<-[:ASSIGNED_TO]-(user:User)のようになります。これらの2つのクエリを評価すると、次の表のように私たちに何かを与えるだろう:につきとして

User-Account-Location 
--------------------- 
u1 | acc1 | loc1 
u2 | acc1 | loc1 
u3 | acc1 | loc1 
u4 | acc1 | loc1 

count(location):最後に

Location-Account 
---------------- 
loc1 | acc1 

Account-User 
------------ 
u1 | acc1 
u2 | acc1 
u3 | acc1 
u4 | acc1 

、のNeo4jは、中間結果に参加し、次の組み合わせの表のようなものを返すために実行しますこのテーブルは4となりますが、count(DISTINCT(location))は1になります。

関連する問題