在有向图中查找树的根

时间:2016-11-14 13:08:38

标签: neo4j cypher

我有一个树结构,如node(1) - > node(2) - > node(3)。我将name作为用于检索节点的属性。

给定节点说节点(3),我想检索节点(1)。

查询已尝试:

MATCH(p:Node) - [:HAS *] - >(c:Node)WHERE c.name =“node 3”RETURN p LIMIT 5

但是,无法获得节点1.

1 个答案:

答案 0 :(得分:2)

您的查询不仅会返回"节点1",而且它至少应该包含一个包含它的路径。可以过滤路径只能让一个遍历到根目录的路径,但是:

MATCH (c:Node {name: "node 3"})<-[:HAS*0..]-(p:Node)
// The root does not have any incoming relationship
WHERE NOT (p)<-[:HAS]-()
RETURN p

注意使用0长度,它匹配所有情况,包括起始节点 根目录的情况。

有趣的事实:即使你有一个Node:name的索引,也不会被使用(除非你使用Neo4j 3.1,它似乎至少从3.1 Beta2开始修复)而你必须明确指定它。

MATCH (c:Node {name: "node 3"})<-[:HAS*0..]-(p:Node)
USING INDEX c:Node(name)
WHERE NOT (p)<-[:HAS]-()
RETURN p

在第一个查询上使用PROFILE(使用数字id属性而不是name):

+-----------------------+----------------+------+---------+-------------------------+----------------------+
| Operator              | Estimated Rows | Rows | DB Hits | Variables               | Other                |
+-----------------------+----------------+------+---------+-------------------------+----------------------+
| +ProduceResults       |              0 |    1 |       0 | p                       | p                    |
| |                     +----------------+------+---------+-------------------------+----------------------+
| +AntiSemiApply        |              0 |    1 |       0 | anon[23], c -- p        |                      |
| |\                    +----------------+------+---------+-------------------------+----------------------+
| | +Expand(All)        |              1 |    0 |       3 | anon[58], anon[67] -- p | (p)<-[:HAS]-()       |
| | |                   +----------------+------+---------+-------------------------+----------------------+
| | +Argument           |              1 |    3 |       0 | p                       |                      |
| |                     +----------------+------+---------+-------------------------+----------------------+
| +Filter               |              1 |    3 |       3 | anon[23], c, p          | p:Node               |
| |                     +----------------+------+---------+-------------------------+----------------------+
| +VarLengthExpand(All) |              1 |    3 |       5 | anon[23], p -- c        | (c)<-[:HAS*]-(p)     |
| |                     +----------------+------+---------+-------------------------+----------------------+
| +Filter               |              1 |    1 |       3 | c                       | c.id == {  AUTOINT0} |
| |                     +----------------+------+---------+-------------------------+----------------------+
| +NodeByLabelScan      |              3 |    3 |       4 | c                       | :Node                |
+-----------------------+----------------+------+---------+-------------------------+----------------------+

Total database accesses: 18

并在第二个:

+-----------------------+----------------+------+---------+-------------------------+------------------+
| Operator              | Estimated Rows | Rows | DB Hits | Variables               | Other            |
+-----------------------+----------------+------+---------+-------------------------+------------------+
| +ProduceResults       |              0 |    1 |       0 | p                       | p                |
| |                     +----------------+------+---------+-------------------------+------------------+
| +AntiSemiApply        |              0 |    1 |       0 | anon[23], c -- p        |                  |
| |\                    +----------------+------+---------+-------------------------+------------------+
| | +Expand(All)        |              1 |    0 |       3 | anon[81], anon[90] -- p | (p)<-[:HAS]-()   |
| | |                   +----------------+------+---------+-------------------------+------------------+
| | +Argument           |              1 |    3 |       0 | p                       |                  |
| |                     +----------------+------+---------+-------------------------+------------------+
| +Filter               |              1 |    3 |       3 | anon[23], c, p          | p:Node           |
| |                     +----------------+------+---------+-------------------------+------------------+
| +VarLengthExpand(All) |              1 |    3 |       5 | anon[23], p -- c        | (c)<-[:HAS*]-(p) |
| |                     +----------------+------+---------+-------------------------+------------------+
| +NodeUniqueIndexSeek  |              1 |    1 |       2 | c                       | :Node(id)        |
+-----------------------+----------------+------+---------+-------------------------+------------------+

Total database accesses: 13