我的树图的 Arangodb 自定义过滤器/访问者 [英] Arangodb custom filter/visitor for my tree graph
问题描述
我有一个有两个边定义的图,如下所示:
I have a graph with two edge definitions like this:
isDepartment: [organisation] -> [organisation]
hasAccess: [user] -> [organisation]
组织嵌套在树中(无循环).有多个没有任何传入 isDepartment
边的顶级组织.
Organisations are nested in a tree (no cycles). There are multiple top-level organisations without any incoming isDepartment
edges.
用户被授予访问一个或多个组织的权限.这些可以是顶级组织,也可以是树下某处的组织.如果用户有权访问某个组织,则它可以访问所有子组织.
Users are granted access to one or more organisations. These can be top-level organisations or organisations somewhere lower down the tree. If a user has access to an organisation, it has access to all child organisations.
我正在尝试构建一个自定义访问者或过滤器,为用户提供所有可访问的组织,包括它的根路径,以及是否可访问的属性.
I am trying to build a custom visitor or filter that gives me all accessible organisations for a user, including it's path to the root, along with a property if they are accessible or not.
例如,采取以下组织结构:
Example, take the following organisation structure:
- 根A
- 部门A.1
- 部门A.2
- 部门B.1
- 部门B.2
- 分部B.2.1
- 部门C.1
- 部门C.2
现在以一个具有
Root A
和Dept 访问权限的用户为例.B.2
.我想生成以下结果树:Now take a user that hasAccess to
Root A
andDept. B.2
. I would like to generate the following result tree:- Root A,可访问:true
- 部门A.1,可访问:true
- 部门A.2、可访问:true
- 部门B.2、可访问:true
- 分部B.2.1,可访问:true
注意
Root C
和Dept.B1
不在结果中,因为用户无法访问它们,也无法访问它们的任何子节点.Note that
Root C
andDept. B1
are not in the result because they are not accessible to the user, nor are any of their children accessible.另请注意,
Root B
已包含在内,但被标记为不可访问
.这是因为用户仅被授予对Root B
的子代的访问权限,而不能访问 root 本身.Also note that
Root B
is included but marked asnot accessible
. This is because teh user is granted access to only a child ofRoot B
but not the root itself.如何编写自定义函数/访问者/过滤器来完成此任务?
How can I write a custom function/visitor/filter that accomplished this?
推荐答案
这确实是一个具有挑战性的问题,非常感谢 ;)
This was indeed a challenging question, thank you very much ;)
您可以通过向 AQL 添加用户定义的函数并在 TRAVERSER 中使用它们来解决此问题.
You can solve this by adding user-defined functions to AQL and use them in the TRAVERSER.
首先我通过arangosh注册了两个AQL访问者函数:
First of all I have registered two AQL visitor functions through arangosh:
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};}")
这些函数只需执行以下操作:
These functions simply do the following:
myvisitor::indirectAccess
将用于向下遍历树.由于在 AQL 中结果始终是一个 Array,我们只需在第一个文档中(如果需要)来存储所有数据.然后我们将值{hasAccess: true}
分配给顶点_key
属性.myvisitor::noAccess
将用于遍历树并以相同的方式存储 '{hasAccess: false}`.
myvisitor::indirectAccess
will be used to traverse down the tree. As in AQL the result is always an Array, we simply at a first document to it (if necessary) to store all the data. Then we assign to the vertexes_key
property the value{hasAccess: true}
.myvisitor::noAccess
will be used to traverse up the tree und will store '{hasAccess: false}` in the same way.
现在我们可以执行以下使用这些访问者的查询:
Now we can execute the following query which makes use of these visitors:
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". - 沿着树
向下
向下走,并将所有内容标记为访问". - 合并
向上
和向下
.
- Find the organizations this user has direct access to.
- Go up the tree
upwards
and mark everything as "noAccess". - Go down the tree
downwards
and mark everything as "access". - Merge
upwards
anddownwards
.
如果您想修改结果格式,您必须更改已注册的访问者功能.
If you would like to modify the result format you have to change the registered visitor functions.
这篇关于我的树图的 Arangodb 自定义过滤器/访问者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!