好的,这是我的数据模型:
(User)-[:ASSIGNED_TO]-(Account)
(Location)-[:BELONGS_TO]->(Account)
(User)-[:ASSIGNED_TO]-(Location)
在我的数据库中有1个帐户,1个位置和16个用户。每个用户都是: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
结果是account
,userCount = 16 (correct)
和locationCount = 16 (incorrect; should be 1)
。如果我将distinct
添加到位置计数count(distinct location)
,我会得到正确的结果(1),如果我删除了用户的OPTIONAL MATCH
,我的位置数也会为1。我知道这与与帐户和位置有关系的用户有关,但我只是想了解为什么没有明显的查询不起作用。还有,有更好的方法来写这个吗?
答案 0 :(得分:1)
这确实有点棘手。这是重写的查询,以显示您正在寻找的模式:
MATCH (account:Account)
WHERE account.id = '123456'
MATCH (location:Location)-[:BELONGS_TO]->(account)<-[:ASSIGNED_TO]-(user:User)
RETURN account, count (location), count (user)
中间有一个帐户,但你不知道每边的数字是多少。 结果集将包含模式的所有匹配项(恰好是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解决了这个问题。按帐户聚合(只有一个没有真正的聚合发生),结果集中有16个位置。 DISTINCT确保您只计算独特的数量。同样的DOES也适用于用户!
看看这个查询,看看差异:
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
希望这有帮助。
此致 汤姆
答案 1 :(得分:0)
如果您在行而不是图表中查看结果,则可以看到实际上有16行数据。每行包含location
,count(location)
实际上返回的行数为location
。
我更喜欢使用distinct
来删除重复项。我们在生产中提供服务,我们在类似的情况下使用distinct
。
答案 2 :(得分: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)
。评估这两个查询会给我们类似下表:
Location-Account
----------------
loc1 | acc1
Account-User
------------
u1 | acc1
u2 | acc1
u3 | acc1
u4 | acc1
最后,Neo4j对中间结果执行连接,返回类似下面的组合表:
User-Account-Location
---------------------
u1 | acc1 | loc1
u2 | acc1 | loc1
u3 | acc1 | loc1
u4 | acc1 | loc1
count(location)
根据此表格为4,而count(DISTINCT(location))
为1:)