我正在以两种不同的方式进行一些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)
在第二种方法中,我没有在任何地方更改buyer_list,我只计算卖家团队成员和卖家组织成员。但买家的数量正在发生变化。为什么呢?
看看这张图片,买家的数量只有1,但为什么计数会返回45k。
并且,为什么90k db命中45k节点?任何具体原因以及如何在此处减少db命中。
答案 0 :(得分:1)
要记住的一个关键事项是Neo4j中的查询会构建行和列。当您在断开连接的模式之间执行匹配时,您倾向于获得针对当前行的笛卡尔积(并且您可以在查询计划中看到它)。也就是说,笛卡尔产品不一定是错误或坏事。如果没有笛卡尔产品,那么您的指南列表中的所有卖家都无法匹配,而且它只是针对您的单行的笛卡尔产品。
如果您在卖家匹配后立即返回所有值,您会看到每一行都有不同的卖家,但所有其他字段(包括买家)都是相同的。
您希望获得一系列不同的值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