在我的应用程序中,我设置了角色,为用户提供对其他用户资产的不同级别的访问权限。
我有此查询返回资产BobsPrivate
,其中请求的用户是Bob
MATCH (u:User {name: 'Bob' })
MATCH (n:Asset:Album {name:'BobsPrivate'})
WHERE (u)-[:CREATED|:FRIENDS_CAN_READ]->(n) OR (n)<-[:CAN_READ]-()<-[:BELONGS_TO]-(u)
RETURN n
我的所有查询都来自节点的REST API。
这按预期工作并返回资产,因为其中一个关系存在,如果我传递一个不存在的资产名称,如foo,它按预期工作,不返回任何内容。
当我传递用户James
和BobsPrivate
时,它也没有返回任何内容,正如您所期望的那样,但我希望返回不同的内容。
我的问题是,我得到了与不存在的资产相同的结果,并且与后者不存在的关系等同于没有适当的访问级别。
如何构造我的查询,以便我可以返回两个不同的结果,以便我可以在我的控制器中以不同的方式处理HTTP响应(404,403)?我还需要在UPDATE
和DELETE
方法中使用相同的原则。
编辑:
我稍微更改了我的查询,它给了我正在寻找的内容,但它确实引入了另一个MATCH
,所以我仍然愿意接受建议
OPTIONAL MATCH (u:User {name: 'Bob' })
OPTIONAL MATCH (n:Asset:Album {name:'BobsPrivate'})
WHERE (u)-[:CREATED|:FRIENDS_CAN_READ]->(n) OR (n)<-[:CAN_READ]-()<-[:BELONGS_TO]-(u)
WITH n
OPTIONAL MATCH (l:Asset:Album {name:'BobsPrivate'})
RETURN n AS ASSET, l IS NOT NULL AS ASSET_EXISTS, CASE WHEN n IS NOT NULL AND l IS NOT NULL THEN true ELSE
这让我做的是按原样返回Asset
,而不需要根据关系进行任何额外的向下钻取,这样我就可以返回一个有用的布尔值,我的控制器可以使用它。
我是NEO4J的新手,我很确定会有更好的方式,所以如果你知道的话,我会非常感激。
答案 0 :(得分:1)
我尝试达到预期行为的5分钟:
MATCH (u:User {name: 'Bob' })
MATCH (n:Asset:Album {name:'BobsPrivate'})
RETURN
n,
EXISTS((u)-[:CREATED|:FRIENDS_CAN_READ]->(n)) as isDirectAccessible,
EXISTS((n)<-[:CAN_READ]-()<-[:BELONGS_TO]-(u)) as isIndirectAccessible
我们正在分别检索所有事实:
然后,在客户端,我们可以决定我们将如何处理。例如:
删除查询示例:
MATCH (u:User {name: 'Bob' })
MATCH (n:Asset:Album {name:'BobsPrivate'})
WITH
n,
EXISTS((u)-[:CREATED|:FRIENDS_CAN_READ]->(n)) as isDirectAccessible,
EXISTS((n)<-[:CAN_READ]-()<-[:BELONGS_TO]-(u)) as isIndirectAccessible
WITH n, isDirectAccessible, isIndirectAccessible,
(CASE
WHEN isDirectAccessible OR isIndirectAccessible THEN n
ELSE null
END) as deletableObject
DETACH DELETE deletableObject
RETURN (deletableObject IS NOT NULL) as isDeleted, isDirectAccessible, isIndirectAccessible
同样的原则在这里工作:
注意:我觉得这可能不是最好的方法。但是,嘿,它有效。