我的树图的 Arangodb 自定义 filter/visitor
Arangodb custom filter/visitor for my tree graph
我有一个包含两条边定义的图,如下所示:
isDepartment: [organisation] -> [organisation]
hasAccess: [user] -> [organisation]
组织嵌套在树中(无循环)。有多个 top-level 组织没有任何传入 isDepartment
边缘。
用户被授予访问一个或多个组织的权限。这些可以是 top-level 个组织或树下某处的组织。如果用户有权访问组织,则它可以访问所有 child 个组织。
我正在尝试构建一个自定义访问者或过滤器,为我提供用户的所有可访问组织,包括它的根路径,以及 属性 是否可访问。
例如,采用以下组织结构:
- 根A
- 部门。 A.1
- 部门。 A.2
- 根 B
- 部门。 B.1
- 部门。 B.2
- 分部。 B.2.1
- C 根目录
- 部门。 C.1
- 部门。 C.2
现在拿一个可以访问 Root A
和 Dept. B.2
的用户。我想生成以下结果树:
- 根 A,可访问:true
- 部门。 A.1、可访问性:true
- 部门。 A.2、可访问:true
- 根 B,可访问:false
- 部门。 B.2、可访问性:true
- 分部。 B.2.1、可访问:true
请注意,Root C
和 Dept. B1
不在结果中,因为用户无法访问它们,它们的任何 children 也无法访问。
另请注意,Root B
已包含但标记为 not accessible
。这是因为用户仅被授予访问 Root B
的 child 而不是根本身。
我如何编写自定义的 function/visitor/filter 来实现这一点?
这确实是一个具有挑战性的问题,非常感谢;)
您可以通过向 AQL 添加用户定义的函数并在 TRAVERSER 中使用它们来解决此问题。
首先我通过arangosh注册了两个AQL访问者函数:
var aqlfunctions = require("org/arangodb/aql/functions");
aqlfunctions.register("myvisitor::indirectAccess", "function (config, result, vertex) { if(result.length === 0) {result.push({});} result[0][vertex._key] = {hasAccess: true};}")
aqlfunctions.register("myvisitor::noAccess", "function (config, result, vertex) { if (result.length === 0) {result.push({});} result[0][vertex._key] = {hasAccess: false};}")
这些函数仅执行以下操作:
myvisitor::indirectAccess
将用于向下遍历树。由于在 AQL 中结果始终是一个数组,我们只需在第一个文档中向它(如果需要)存储所有数据。然后我们给顶点 _key
属性 赋值 {hasAccess: true}
.
myvisitor::noAccess
将用于遍历树并以相同的方式存储 '{hasAccess: false}`。
现在我们可以执行以下使用这些访问者的查询:
FOR x IN GRAPH_NEIGHBORS(@graph, @userId, {direction: 'outbound'})
LET upwards = TRAVERSAL(organisation, isDepartment, x, 'inbound', {visitor: 'myvisitor::noAccess'})[0]
LET downwards = TRAVERSAL(organisation, isDepartment, x, 'outbound', {visitor: 'myvisitor::indirectAccess'})[0]
RETURN MERGE(upwards, downwards)
简短说明:
- 查找该用户可以直接访问的组织。
- 上树
upwards
并将所有内容标记为 "noAccess"。
- 沿着树
downwards
向下移动并将所有内容标记为 "access"。
- 合并
upwards
和 downwards
。
如果您想修改结果格式,您必须更改已注册的访客功能。
我有一个包含两条边定义的图,如下所示:
isDepartment: [organisation] -> [organisation]
hasAccess: [user] -> [organisation]
组织嵌套在树中(无循环)。有多个 top-level 组织没有任何传入 isDepartment
边缘。
用户被授予访问一个或多个组织的权限。这些可以是 top-level 个组织或树下某处的组织。如果用户有权访问组织,则它可以访问所有 child 个组织。
我正在尝试构建一个自定义访问者或过滤器,为我提供用户的所有可访问组织,包括它的根路径,以及 属性 是否可访问。
例如,采用以下组织结构:
- 根A
- 部门。 A.1
- 部门。 A.2
- 根 B
- 部门。 B.1
- 部门。 B.2
- 分部。 B.2.1
- C 根目录
- 部门。 C.1
- 部门。 C.2
现在拿一个可以访问 Root A
和 Dept. B.2
的用户。我想生成以下结果树:
- 根 A,可访问:true
- 部门。 A.1、可访问性:true
- 部门。 A.2、可访问:true
- 根 B,可访问:false
- 部门。 B.2、可访问性:true
- 分部。 B.2.1、可访问:true
请注意,Root C
和 Dept. B1
不在结果中,因为用户无法访问它们,它们的任何 children 也无法访问。
另请注意,Root B
已包含但标记为 not accessible
。这是因为用户仅被授予访问 Root B
的 child 而不是根本身。
我如何编写自定义的 function/visitor/filter 来实现这一点?
这确实是一个具有挑战性的问题,非常感谢;)
您可以通过向 AQL 添加用户定义的函数并在 TRAVERSER 中使用它们来解决此问题。
首先我通过arangosh注册了两个AQL访问者函数:
var aqlfunctions = require("org/arangodb/aql/functions");
aqlfunctions.register("myvisitor::indirectAccess", "function (config, result, vertex) { if(result.length === 0) {result.push({});} result[0][vertex._key] = {hasAccess: true};}")
aqlfunctions.register("myvisitor::noAccess", "function (config, result, vertex) { if (result.length === 0) {result.push({});} result[0][vertex._key] = {hasAccess: false};}")
这些函数仅执行以下操作:
myvisitor::indirectAccess
将用于向下遍历树。由于在 AQL 中结果始终是一个数组,我们只需在第一个文档中向它(如果需要)存储所有数据。然后我们给顶点_key
属性 赋值{hasAccess: true}
.myvisitor::noAccess
将用于遍历树并以相同的方式存储 '{hasAccess: false}`。
现在我们可以执行以下使用这些访问者的查询:
FOR x IN GRAPH_NEIGHBORS(@graph, @userId, {direction: 'outbound'})
LET upwards = TRAVERSAL(organisation, isDepartment, x, 'inbound', {visitor: 'myvisitor::noAccess'})[0]
LET downwards = TRAVERSAL(organisation, isDepartment, x, 'outbound', {visitor: 'myvisitor::indirectAccess'})[0]
RETURN MERGE(upwards, downwards)
简短说明:
- 查找该用户可以直接访问的组织。
- 上树
upwards
并将所有内容标记为 "noAccess"。 - 沿着树
downwards
向下移动并将所有内容标记为 "access"。 - 合并
upwards
和downwards
。
如果您想修改结果格式,您必须更改已注册的访客功能。