Neo4j 2.0如何计算CASE子句中的关系?

时间:2014-01-07 20:01:59

标签: count neo4j case cypher relationships

我一直在编写一个密码查询来计算所有节点的标签,属性或关系,其中包含用户输入的条件。当我执行此查询时,我想要计算具有唯一标签名称的所有节点(我已完成)。 我还想要计算包含特定关系的所有节点。

这是查询的一部分,它返回具有标签的所有节点的计数:Fruit,Lesson,Tech和TestData。我遗漏了WHERE子句,因为它很长。

match (n)
return 
sum(CASE when any(l IN labels(n) WHERE l='Fruit') THEN 1 ELSE 0 END) AS Fruit,      
sum(CASE when any(l IN labels(n) WHERE l='Lesson') THEN 1 ELSE 0 END) AS Lesson,
sum(CASE when any(l IN labels(n) WHERE l='Tech') THEN 1 ELSE 0 END) AS Tech,
sum(CASE when any(l IN labels(n) WHERE l='TestData') THEN 1 ELSE 0 END) AS TestData

返回

Fruit       Lesson         Tech         TestData
1000        20              100         50

但是,我还想计算具有特定关系的节点数(我提前知道名称),例如“KNOWS”,“IS_A”和“DESTINATION”。例如,如果用户正在搜索单词“knows”并且结果节点具有称为“knows”的关系,那么我将计算该节点。之后,我的查询将报告我找到了20个通过“知道”关系连接的节点。

我想在不排除任何结果节点的情况下执行此操作。注意我没有在match子句中包含任何关系。我仍然希望包含没有关系的节点(我不关心计算它)。

有谁知道怎么做?可以吗?

我正在寻找类似的东西:

match (n)
return
sum(CASE when any(r IN rels(n) WHERE r='KNOWS') THEN 1 ELSE 0 END) AS KNOWS,      
sum(CASE when any(r IN rels(n) WHERE r='IS_A') THEN 1 ELSE 0 END) AS IS_A,
sum(CASE when any(r IN rels(n) WHERE r='DESTINATION') THEN 1 ELSE 0 END) AS DESTINATION,

1 个答案:

答案 0 :(得分:1)

不确定我是否理解了“计算匹配特定关系的节点”和“不排除任何结果节点”的含义。您是指计算节点在每种类型的任何方向上至少有一个关系的情况(例如,如果节点有两个或五个这样的关系,它仍然算作一个),而不是计算关系?或者你的意思是你想要一个与以前的查询计数标签结合使用的子查询?这样做你想要的吗?

MATCH (n)
OPTIONAL MATCH (n)-[r]-()
WITH n, collect(r) as rs
SUM(CASE WHEN ANY(l IN labels(n) WHERE l='Fruit') THEN 1 ELSE 0 END) AS Fruit,
SUM(CASE WHEN ANY(l IN labels(n) WHERE l='Lesson') THEN 1 ELSE 0 END) AS Lesson,
SUM(CASE WHEN ANY(l IN labels(n) WHERE l='Tech') THEN 1 ELSE 0 END) AS Tech,
SUM(CASE WHEN ANY(l IN labels(n) WHERE l='TestData') THEN 1 ELSE 0 END) AS TestData,
SUM(CASE WHEN ANY(r IN rs WHERE type(r)='KNOWS') THEN 1 ELSE 0 END) AS KNOWS,
SUM(CASE WHEN ANY(r IN rs WHERE type(r)='IS_A') THEN 1 ELSE 0 END) AS IS_A,
SUM(CASE WHEN ANY(r IN rs WHERE type(r)='DESTINATION') THEN 1 ELSE 0 END) AS DESTINATION

你可以尝试的一些可能是改进的东西,就是要匹配你想要明确计算的每一件事,计算它,然后用WITH进行计数,直到你回来。如果您的数据库中存在许多您不计算的内容,那么这将带来特别的好处,无论如何,上述查询中的内容将被匹配和评估。所以你可以尝试像

这样的东西
MATCH (n:Fruit)
WITH count(n) as Fruit
MATCH (n:'Lesson')
WITH Fruit, count(n) as Lesson
MATCH (n:'Tech')
WITH Fruit, Lesson, count(n) as Tech
MATCH (n:TestData)
WITH Fruit, Lesson, Tech, count(n) as TestData
MATCH (n)-[:KNOWS]-()
WITH Fruit, Lesson, Tech, TestData, count(n) as KNOWS
MATCH (n)-[:IS_A]-()
WITH Fruit, Lesson, Tech, TestData, KNOWS, count(n) as IS_A
MATCH (n)-[:DESTINATION]-()
RETURN Fruit, Lesson, Tech, TestData, KNOWS, IS_A, count(n) as DESTINATION

我不知道它会对您的数据产生多大的影响,但是尽可能使用较窄或特定的模式,而不是使用宽泛的模式然后过滤。可能值得对两个查询进行分析并进行比较。