我有一个图表,其中包含表示权限层次结构中的角色的节点。权限层次结构如下所示:
(:role:owners)-[:CONTACT]->(:role:admins)-[:CONTACT]->(:role:employees)
-[:CONTACT]->(:role:contacts)
然后将联系人附加到每个角色节点,如下所示:
(:contact {id: "1"})-[:CONTACT]->(:role:owners)
(:contact {id: "2"})-[:CONTACT]->(:role:employees)
我试图运行以下查询,如果用户是所有者或管理员(例如联系人1),则返回:contacts
角色,如果用户是:employees
角色,则返回MATCH (c:contact {id: "1"})
WITH c
MATCH (g:role)
WHERE
(c)-[:CONTACT*1..2]->(:admins)-->(:employees)-->(g:contacts) OR
(c)-[:CONTACT]->(g:employees)
RETURN DISTINCT c, g
角色员工(如联系人2)。
c g
(:contact {id: "1"}) (:role:contacts)
Returned 1 row
预期结果
c g
(:contact {id: "1"}) (:role:owners)
(:contact {id: "1"}) (:role:admins)
(:contact {id: "1"}) (:role:employees)
(:contact {id: "1"}) (:role:contacts)
Returned 4 rows
实际结果
:role
我认为此查询只会返回包含:contacts
标签和:employees
或:owners
的节点,但它也会返回包含:admins
和{{1}的节点}标签。
为什么要返回这些额外的节点,如何防止它这样做呢?这是针对Neo4j 2.1.2。
其他信息
我想我已经发现了这个错误。如果找不到有效路径,则看起来正在删除标签检查。在以下示例中,请注意(c1)
和(g:projectcontacts)
之间没有路径,因为没有(:projectcontacts)
个节点。在这种情况下,将删除projectcontacts
匹配,并返回匹配(c1)-[:CONTACT*1..3]->(g:role)
的所有节点。
这是在Neo4j 2.1.3服务器上:
neo4j-sh (?)$ CREATE
> (o:role:owners {name:"Owners"})-[:CONTACT]->(:role:admins {name:"Admins"})-[:CONTACT]->
> (e:role:employees {name:"Employees"})-[:CONTACT]->(:role:contacts {name:"Contacts"})
> CREATE
> (c1:contact {id: "test1"})-[:CONTACT]->(o)
> CREATE
> (c2:contact {id: "test2"})-[:CONTACT]->(e)
>
> WITH c1
>
> MATCH (g:role)
> WHERE
> (c1)-[:CONTACT*1..2]->(:admins)-->(:employees)-->(g:contacts) OR
> (c1)-[:CONTACT]->(g:employees) OR
> (c1)-[:CONTACT*1..3]->(g:projectcontacts)
> RETURN DISTINCT c1, g;
+-------------------------------------------------------+
| c1 | g |
+-------------------------------------------------------+
| Node[4439]{id:"test1"} | Node[4438]{name:"Contacts"} |
| Node[4439]{id:"test1"} | Node[4436]{name:"Admins"} |
| Node[4439]{id:"test1"} | Node[4437]{name:"Employees"} |
| Node[4439]{id:"test1"} | Node[4435]{name:"Owners"} |
+-------------------------------------------------------+
4 rows
Nodes created: 6
Relationships created: 5
Properties set: 6
Labels added: 10
50 ms
如果我们从匹配查询中删除不存在的节点标签,我们会得到预期的结果。
neo4j-sh (?)$ CREATE
> (o:role:owners {name:"Owners"})-[:CONTACT]->(:role:admins {name:"Admins"})-[:CONTACT]->
> (e:role:employees {name:"Employees"})-[:CONTACT]->(:role:contacts {name:"Contacts"})
> CREATE
> (c1:contact {id: "test1"})-[:CONTACT]->(o)
> CREATE
> (c2:contact {id: "test2"})-[:CONTACT]->(e)
>
> WITH c1
>
> MATCH (g:role)
> WHERE
> (c1)-[:CONTACT*1..2]->(:admins)-->(:employees)-->(g:contacts) OR
> (c1)-[:CONTACT]->(g:employees)
> RETURN DISTINCT c1, g;
+------------------------------------------------------+
| c1 | g |
+------------------------------------------------------+
| Node[4445]{id:"test1"} | Node[4444]{name:"Contacts"} |
+------------------------------------------------------+
1 row
Nodes created: 6
Relationships created: 5
Properties set: 6
Labels added: 10
55 ms
答案 0 :(得分:0)
比尔,
我肯定不知道这一点,但我倾向于猜测问题是你通过在WHERE子句中为它添加标签来重新定义g。应用标签可能会导致g被视为要匹配的模式。
这是对还是错,这是一种方法来进行与问题无关的查询(现在纠正做你想做的事):
MATCH (c1:contact {id : 'test'})
WITH c1
MATCH (c1)-[:CONTACT]->(f:role)-[:CONTACT*1..]->(g:contacts)
WITH c1, CASE WHEN 'employees' IN labels(f) THEN f ELSE g END AS h
RETURN DISTINCT c1, h
恩典与和平,
吉姆