Neo4j - 不适当的匹配计数

Neo4j - Inappropriate Match counts

我正在以两种不同的方式进行一些 x 操作。但是在第二种方法中,匹配查询的计数不合适,这是无法接受的。请指出我遗漏的地方。

第一种方式:

profile
WITH [1234] AS sellers_list,
[12345] AS buyers_list

MATCH (buyer:Person) WHERE buyer.person_guid IN buyers_list
MATCH (seller:Person) WHERE seller.person_guid IN sellers_list

RETURN count(buyer),size(buyers_list),count(seller),size(sellers_list)

这个结果:

第二种方式

profile
WITH [1234] AS sellers_list,
[12345] AS buyers_list

MATCH (seller_member:Person)-[r:TEAM_MEMBER]-(seller_teammate:Person) 
    WHERE seller_member.person_guid IN sellers_list

WITH FILTER(x IN COLLECT(seller_teammate.person_guid) WHERE NOT(x in sellers_list)) AS sellerteam, sellers_list, buyers_list

MATCH (seller_member:Person)-[r:EMPLOYED_BY]->(b:Organization)
MATCH (b)<-[s:EMPLOYED_BY]-(org_member:Person) 
    WHERE seller_member.person_guid=sellers[0]

WITH FILTER(x IN COLLECT(org_member.person_guid) WHERE NOT(x IN sellerteam)) AS org_members,sellers_list,sellerteam,buyers_list 

WITH sellers+sellerteam+org_members AS all_org_members,sellers_list,sellerteam,org_members,buyers_list


MATCH (buyer:Person) WHERE buyer.person_guid IN buyers_list
MATCH (seller:Person) WHERE seller.person_guid IN all_org_members

RETURN count(buyer),size(buyers_list),count(seller),size(sellers_list)

这导致:

在第二种方法中,我没有在任何地方更改buyers_list,我只是统计了卖家团队成员和卖家组织成员而已。但买家的数量正在发生变化。为什么?

分析上述查询显示:

看这张图,买家数只有1,但为什么计数返回45k。

而且,为什么 45k 节点的 90k db 命中率?任何具体原因以及如何减少此处的数据库命中率。

要记住的关键是 Neo4j 中的查询会构建行和列。当您在断开连接的模式之间执行匹配时,您往往会得到针对当前行的笛卡尔积(您可以在查询计划中看到这一点)。也就是说,笛卡尔积不一定是错误或坏的。如果没有笛卡尔积,真的无法匹配您的 guid 列表中的所有卖家,它只是针对您的单行的笛卡尔积。

如果您在卖家匹配后立即返回所有值,您会看到每一行都有一个不同的卖家,但所有其他字段(包括买家)都是相同的。

您需要计算不同值的数量,count(distinct buyer),这应该为您提供预期的买家数量 1。

至于 90k 次命中,NodeUniqueIndexSeek 每次查找需要 2 次 db 命中,而您对 45k 个值执行了查找,因此数学计算得出。

编辑

如果您仍然怀疑,您可以单独尝试大型唯一查找(或者尽可能多地单独查找,同时必须首先查找 45k guid)。

MATCH (p:Person)
WITH p LIMIT 45000
WITH COLLECT(p.person_guid) as guids
// you can always take the above subquery, returning 1, to see the timing of just collecting guids
MATCH (p:Person)
WHERE p.person_guid in guids
RETURN COUNT(p) as count