在neo4j中没有层次结构的多个外连接/可选匹配

时间:2014-08-05 08:34:39

标签: neo4j cypher

我正在尝试匹配neo4j中同一级别的多个外连接。

我的数据库由用户和文章的常见数据组成。对于用户之间的上升和下降,评级计数在单独的边缘上。

----------                                -----------
| User n | -[:rating_positive {weight}]-> | User n2 |
----------                                -----------
     |                                         ^
      \-----[:rating_negative {weight}]-------/

现在我想产生总结这些评级的边缘。

我很想使用多个可选的合并,例如:。

MATCH (n:`User`)
OPTIONAL MATCH (n:`User`)-[rating_positive:rating_positive]-(n2:`User`)
OPTIONAL MATCH (n:`User`)-[rating_negative:rating_negative]-(n2:`User`)
RETURN n.uid, n2.uid, rating_positive.weight, rating_negative.weight

但是:在这个例子中,我得到的所有用户都没有任何正面评级,而且所有用户的评分为,但没有评分为负值。所以OPTIONAL MATCH中似乎有一个序列。

如果我交换“可选比赛”的顺序,我会得到那些只有负面评价而不是那些具有正面评级的评分。

  • 所以“OPTIONAL MATCH”在某种程度上是一个只有在第一个时才的序列 顺序是满足我从第二个得到的东西,依此类推?

  • 有解决方法吗?

Neo4j版本是2.1.3。


P.S:

与NULL相比更令人困惑的匹配似乎不起作用。所以这个查询:

MATCH (n:`User`)
OPTIONAL MATCH (n:`User`)-[rating_positive:rating_positive]-(n2:`User`)
OPTIONAL MATCH (n:`User`)-[rating_negative:rating_negative]-(n2:`User`)
WHERE rating_positive IS NULL AND rating_negative IS NOT NULL
RETURN n.uid, n2.uid, rating_positive.weight, rating_negative.weight

会给我很多带有rating_negative和NON NULL rating_positive的边。我不知道WHERE中的空匹配发生了什么?

无论如何,我找到了一种使用“coalesce”将空值重新编码为0的方法:

MATCH (n:`User`)
OPTIONAL MATCH (n:`User`)-[rating_positive:rating_positive]-(n2:`User`)
OPTIONAL MATCH (n:`User`)-[rating_negative:rating_negative]-(n2:`User`)
WITH n, n2, coalesce(rating_positive.weight, 0) AS rating_positive, coalesce(rating_negative.weight, 0) as rating_negative
WHERE rating_positive = 0 AND rating_negative > 0
RETURN n.uid, n2.uid, rating_positive, rating_negative

使用此查询,它可以按预期工作。

2 个答案:

答案 0 :(得分:1)

我认为不仅仅是可选比赛的排序,而是你绑定了n2的事实。 因此,下一个可选匹配仅限于匹配在前一个匹配中被识别为n2候选的节点。因此看起来可选匹配的顺序会影响它。 如果您查看我在此处http://console.neo4j.org/r/lrp55o设置的小样本图表,请执行以下查询

MATCH (n:User)
OPTIONAL
MATCH (n)-[:rating_negative]->(n2)
OPTIONAL
MATCH (n)-[:rating_positive]->(n2)
RETURN n,n2

返回B - [:rating_negative] - > C和C - [:rating_negative] - > D但它省略了A - [:rating_positive] - > B.

rating_negative的第一个可选匹配将C和D绑定为" n2"的节点。第二个可选匹配找不到n具有对C或D的rating_positive,因此得到结果。

我有点不清楚你要对查询和空检查做什么,但是联合将是一种给你所有正面和负面关系的方法(你可以添加你的过滤器):< / p>

MATCH (n:User)
OPTIONAL
MATCH (n)-[rating:rating_negative]->(n2)
RETURN n,n2,rating.weight
UNION ALL 
MATCH (n:User)
OPTIONAL
MATCH (n)-[rating:rating_positive]->(n2)
RETURN n, n2, rating.weight

如果这不是您正在寻找的内容,http://console.neo4j.org?init=0上的一个小子图会很好地帮助您。

编辑:由于评论表明在一对用户之间需要评级总和,因此以下查询可以完成这项工作:

MATCH (u:User)-[rating:rating_positive|:rating_negative]->(u2)
RETURN u,u2,sum(rating.weight) 

答案 1 :(得分:-1)

我无法完全确定这是否是导致您出现问题的原因,但在我看来,您应该省略OPTIONAL MATCH条款中的标签。

也许尝试下面的查询

MATCH (n:`User`)
OPTIONAL MATCH (n)-[rating_positive:rating_positive]-(n2:`User`)
OPTIONAL MATCH (n)-[rating_negative:rating_negative]-(n2)
RETURN n.uid, n2.uid, rating_positive.weight, rating_negative.weight

也可能值得包括关系方向。

MATCH (n:`User`)
OPTIONAL MATCH (n)-[rating_positive:rating_positive]->(n2:`User`)
OPTIONAL MATCH (n)-[rating_negative:rating_negative]->(n2)
RETURN n.uid, n2.uid, rating_positive.weight, rating_negative.weight