OrientDB选择两个相关的顶点

时间:2015-09-30 16:58:57

标签: sql orientdb

我的方案如下所示enter image description here

我想查询数据库,以便得到以下结果,

resource.name = 'Plan A' and user.name = 'Edi'

其中

SELECT name, 
       out('hasARole').out('ofType').in('isOfType')[name = 'Plan A'].name, 
       set(out('hasARole').out('hasA').name) as permission 
FROM user 
WHERE name = 'Edi'

我上面的查询是

User    Resource      Permissions

Adrian   Plan A        [view,edit, delete]

应该显示

resource.name = 'Plan A' and user.name = 'Adrian'

如果我将其更改为,

其中

SELECT name, 
       out('hasARole').out('ofType').in('isOfType')[name = 'Plan A'].name, 
       set(out('hasARole').out('hasA').name) as permission 
FROM user 
WHERE name = 'Adrian'

我上面的查询是

{{1}}

现在,只要用户在另一种资源上没有其他角色,上述查询就会起作用。例如如果 Edi 管理角色让我们说工作区的资源类型,那么该查询会让我回复所有权限< strong>管理员会有,而不仅仅是查看,因为他只对计划A

拥有查看权限

1 个答案:

答案 0 :(得分:2)

我的答案使用了以下图表。请注意,我已使用原始边缘更正了一些错误。

Tweaked Graph

我看到了许多可能的问题查询。我有点困惑为什么你想要在查询中返回用户和资源,因为您可能已经拥有这些记录,因为您使用它们来创建查询。您不能将完整记录“嵌套”在结果中(除非您使用JSON)。除此之外,查询名称字段,只返回名称字段对我来说似乎有点荒谬 - 但也许你这样做是为了简化问题。无论如何,以下查询将帮助您获得所需的结果。

我的第一个想法是运行查询以获取与资源相关的所有角色。然后,我们对这些结果运行查询,以筛选包含用户的角色。这看起来如下;

select from (
    select expand(out('isOfType').in('ofType')) from Resource where name = "Plan A"
) where in('hasARole') contains first((select from User where name = "Edi"))

此查询只能正确返回Edi和Adrian的查看者记录。

我的第二个想法是对与资源相关的角色(类似于上面)运行1个查询,为与用户相关的角色运行另一个查询,然后找到相交。这看起来如下所示,并提供与上述查询相同的结果;

select expand(intersect) from (
    select intersect($resource_roles, $user_roles)
    let
    $resource_roles = (select expand(out('isOfType').in('ofType')) from Resource where name = "Plan A"),
    $user_roles = (select expand(out('hasARole')) from User where name = "Edi")
)

现在,如果你确实想要1个结果中的用户,资源和权限,你可以使用以下或者变体;

select first($user).name as User, first($resource).name as Resource, intersect(resource_roles,     user_roles).name as Permissions from (
    select $resource.out('isOfType').in('ofType') as resource_roles, $user.out('hasARole') as user_roles
    let
    $resource = (select from Resource where name = "Plan A"),
    $user = (select from User where name = "Edi")
)

select first($user).name as User, first($resource).name as Resource, intersect($resource_roles, $user_roles).name as Permissions
let
$resource = (select from Resource where name = "Plan A"),
$resource_roles = (select expand(out('isOfType').in('ofType')) from $parent.$resource),
$user = (select from User where name = "Edi"),
$user_roles = (select expand(out('hasARole')) from $parent.$user)