我的树形图的Arangodb自定义过滤器/访问者 [英] Arangodb custom filter/visitor for my tree graph

查看:96
本文介绍了我的树形图的Arangodb自定义过滤器/访问者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有两个边缘定义的图形,如下所示:

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
    • Root A
      • Dept. A.1
      • Dept. A.2
      • 部门B.1
      • 部门B.2
      • 子部门. B.2.1
      • 部门C.1
      • 部门C.2

      现在将具有访问权限的用户带到Root ADept. B.2.我想生成以下结果树:

      Now take a user that hasAccess to Root A and Dept. B.2. I would like to generate the following result tree:

      • A根,可访问:true
        • 部门A.1,可访问:true
        • 部门A.2,可访问:true
        • Root A, accessible: true
          • Dept. A.1, accessible: true
          • Dept. A.2, accessible: true
          • 部门B.2,可访问:true
          • 子部门. B.2.1,可访问:true

          请注意,Root CDept. B1不在结果中,因为用户无法访问它们,也无法访问其任何子级.

          Note that Root C and Dept. B1 are not in the result because they are not accessible to the user, nor are any of their children accessible.

          还请注意,已包含Root B,但将其标记为not accessible.这是因为该用户仅被授予对Root B的子级的访问权限,而没有对根目录本身的访问权限.

          Also note that Root B is included but marked as not accessible. This is because teh user is granted access to only a child of Root 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中一样,结果始终是一个数组,我们只需在第一个文档(如有必要)中存储所有数据即可.然后,将值{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)
          

          简短说明:

          1. 查找该用户可以直接访问的组织.
          2. 上树upwards并将所有内容标记为"noAccess".
          3. 从树上走下downwards并将所有内容标记为访问".
          4. 合并upwardsdownwards.
          1. Find the organizations this user has direct access to.
          2. Go up the tree upwards and mark everything as "noAccess".
          3. Go down the tree downwards and mark everything as "access".
          4. Merge upwards and downwards.

          如果要修改结果格式,则必须更改已注册的访问者功能.

          If you would like to modify the result format you have to change the registered visitor functions.

          这篇关于我的树形图的Arangodb自定义过滤器/访问者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆