NEO4J密码查询:Where子句中的关系方向错误 [英] NEO4J Cypher Query: Relationship Direction Bug in Where Clause

查看:113
本文介绍了NEO4J密码查询:Where子句中的关系方向错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

样本数据:

样品查询

CREATE (a1:A {title: "a1"})
CREATE (a2:A {title: "a2"})
CREATE (a3:A {title: "a3"})

CREATE (b1:B {title: "b1"})
CREATE (b2:B {title: "b2"})

MATCH (a:A {title: "a1"}), (b:B {title: "b1"})
CREATE (a)-[r:LINKS]->(b)

MATCH (a:A {title: "a2"}), (a1:A {title: "a1"}) 
CREATE (a)-[:CONNECTED]->(a1)

MATCH (a:A), (b:B) return a,b


目标:在where子句中找到一些连接

Objective: Finding some connections in the where clause

现在,让我们写一些变体来查找未直接连接到B的A(a2和b3)

Now lets write some variations to find A's not directly connected to B (a2 and b3)

// Q1. Both work fine
MATCH (a:A) WHERE (a)--(:B) RETURN a
MATCH (a:A) WHERE (:B)--(a) RETURN a

// Q2. Works
MATCH (a:A)-[r]-(b:B) WHERE (a)-[r]-(b) RETURN a

// Q3. Fails
MATCH (a:A)-[r]-(b:B) WHERE (b)-[r]-(a) RETURN a

有人知道,即使将方向指定为双向,为什么Q2,Q3的行为方式也不相同? 这是NEO4J错误吗?

Any idea why Q2, Q3 are not behaving the same way even if the direction is specified as bi-directional? Is this a NEO4J bug?

stdob 上获得的所有积分. com/a/49798661/1897935>此 答案以缩小 减少了我其他查询中发生的异常.

All credits to stdob at this answer for narrowing down the anomaly that was happening in my other query.


更新:将相同内容发布到 NEO4J GitHub问题

更新:NEO4J已接受此错误,因为它将在3.1版中进行修复

Update: NEO4J has accepted this as a bug are will be fixing it at 3.1

推荐答案

虽然这可能不是一个完整的答案,但有关评论的信息太多.希望这可以提供一些有用的见识.

While this might not be a complete answer, it is too much info for a comment. This should hopefully provide some helpful insight though.

我认为这是一个错误.以下是应该从样本数据中得出相同结果的一些变体.它们都应该通过给定的数据通过(通过返回任何内容)

I would consider this a bug. Below are some variations of what should give the same results from the sample data. They should all pass with the given data (pass being return anything)

MATCH (a:A)-[r]-(b:B) WHERE (b)-[r]-(a) RETURN *->失败

删除r
MATCH (a:A)--(b:B) WHERE (b)--(a) RETURN *->通过
MATCH (a:A)-[r]-(b:B) WHERE (b)--(a) RETURN *->通过

remove r
MATCH (a:A)--(b:B) WHERE (b)--(a) RETURN * -> pass
MATCH (a:A)-[r]-(b:B) WHERE (b)--(a) RETURN * -> pass

添加方向
MATCH (a:A)-[r]-(b:B) WHERE (b)<-[r]-(a) RETURN *->通过

add direction
MATCH (a:A)-[r]-(b:B) WHERE (b)<-[r]-(a) RETURN * -> pass

倒序
MATCH (a:A)-[r]-(b:B) WHERE (a)-[r]-(b) RETURN *->通过

reverse order
MATCH (a:A)-[r]-(b:B) WHERE (a)-[r]-(b) RETURN * -> pass

然后,通过失败的测试的个人资料

And, from the profile of the failed test

+---------------------+----------------+------+---------+-----------+--------------+
| Operator            | Estimated Rows | Rows | DB Hits | Variables | Other        |
+---------------------+----------------+------+---------+-----------+--------------+
| +ProduceResults     |              1 |    0 |       0 | a         | a            |
| |                   +----------------+------+---------+-----------+--------------+
| +SemiApply          |              1 |    0 |       0 | a, b, r   |              |
| |\                  +----------------+------+---------+-----------+--------------+
| | +ProjectEndpoints |              1 |    0 |       0 | a, b, r   | r, b, a      |
| | |                 +----------------+------+---------+-----------+--------------+
| | +Argument         |              2 |    1 |       0 | a, b, r   |              |
| |                   +----------------+------+---------+-----------+--------------+
| +Filter             |              2 |    1 |       1 | a, b, r   | a:A          |
| |                   +----------------+------+---------+-----------+--------------+
| +Expand(All)        |              2 |    1 |       3 | a, r -- b | (b)-[r:]-(a) |
| |                   +----------------+------+---------+-----------+--------------+
| +NodeByLabelScan    |              2 |    2 |       3 | b         | :B           |
+---------------------+----------------+------+---------+-----------+--------------+

和等效的通过测试(反向顺序)

and the equivalent passed test (reverse order)

+---------------------+----------------+------+---------+-----------+--------------+
| Operator            | Estimated Rows | Rows | DB Hits | Variables | Other        |
+---------------------+----------------+------+---------+-----------+--------------+
| +ProduceResults     |              1 |    1 |       0 | a         | a            |
| |                   +----------------+------+---------+-----------+--------------+
| +SemiApply          |              1 |    1 |       0 | a, b, r   |              |
| |\                  +----------------+------+---------+-----------+--------------+
| | +ProjectEndpoints |              1 |    0 |       0 | a, b, r   | r, a, b      |
| | |                 +----------------+------+---------+-----------+--------------+
| | +Argument         |              2 |    1 |       0 | a, b, r   |              |
| |                   +----------------+------+---------+-----------+--------------+
| +Filter             |              2 |    1 |       1 | a, b, r   | a:A          |
| |                   +----------------+------+---------+-----------+--------------+
| +Expand(All)        |              2 |    1 |       3 | a, r -- b | (b)-[r:]-(a) |
| |                   +----------------+------+---------+-----------+--------------+
| +NodeByLabelScan    |              2 |    2 |       3 | b         | :B           |
+---------------------+----------------+------+---------+-----------+--------------+

注意每个步骤1之后的行数.相同的计划不应产生不同的结果.我可以推测这是一个与图形修剪快捷方式有关的错误(即,一旦Neo4j在一个方向上遍历一条边,它就不会在同一匹配中遍历同一条边.这是一个防循环故障保护/性能特征)因此,从理论上讲,在将匹配部分的where部分中的顺序颠倒之后,Neo4j必须遍历修剪的边缘以验证关系.如果方向相同,则会自动通过.如果Neo4j尝试反向执行相同的检查,则会失败,因为该边缘已被修剪. (不过,这只是理论上的问题.从技术上讲,失败的验证是反向的r验证)

Notice the row count after step 1 in each. The same plan should not produce different results. I can speculate that is is a bug related to the graph pruning shortcuts (namely, once Neo4j traverses an edge in one direction, it will not traverse back on the same edge in the same match. This is an anti-cycle fail-safe/performance feature) So, in theory, after reversing the order in the where part from the match part, Neo4j has to traverse a pruned edge to validate the relationship. If it is the same direction, it auto-passes. If Neo4j tries to do the same check in reverse, it fails because that edge has been pruned. (This is just theory though. The validation that is failing is technically on the r validation in reverse)

这篇关于NEO4J密码查询:Where子句中的关系方向错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆