如何使用 gremlin 查询权限图?
How do I query a permissions graph using gremlin?
我有下图:
我正在使用 Tinkergraph 来尝试找出:
- 用户#1是否对资源#1具有"read"权限? (它没有)
- User#2 是否对 Resource#1 具有 "write" 权限? (确实如此)。
我还试图找到一个不特定于这个确切图形的查询,因为在现实生活模型中,它们之间可能存在多个层次角色。我刚刚开始掌握 Gremlin 语法,但我发现这个特定的查询难以捉摸。这是创建上图的代码:
Graph graph = TinkerGraph.open();
Vertex user1 = graph.addVertex(T.label, "user", T.id, 1, "name", "marko");
Vertex user2 = graph.addVertex(T.label, "user", T.id, 2, "name", "vadas");
Vertex role1 = graph.addVertex(T.label, "role", T.id, 3, "name", "role_1");
Vertex role2 = graph.addVertex(T.label, "role", T.id, 4, "name", "role_2");
Vertex resource1 = graph.addVertex(T.label, "resource", T.id, 5, "name", "resource_1");
Vertex resource2 = graph.addVertex(T.label, "resource", T.id, 6, "name", "resource_2");
user1.addEdge("read", resource2, T.id, 7);
user1.addEdge("member", role2, T.id, 8);
user2.addEdge("owns", resource2, T.id, 9);
user2.addEdge("member", role1, T.id, 10);
role1.addEdge("child_of", role2, T.id, 11);
role1.addEdge("read", resource1, T.id, 12);
role2.addEdge("write", resource1, T.id, 13);
role2.addEdge("write", resource2, T.id, 14);
我目前尝试回答问题 #1 是使用 repeat
,从 User#1 开始,然后沿着路径找到 "outEdge"标签 "read" 通向顶点 Resource#1.
啊哈,在我写这篇文章的时候,我可能刚刚弄明白了,但由于我是 Gremlin 的新手,也许熟悉 Gremlin 的人可以对其进行理智检查,或者告诉我是否有更好的方法?如果没有,那么也许这会对试图解决同样问题的其他人有所帮助。
q1 = graph.traversal().V(user1.id())
.repeat(__.out().simplePath())
.until(__.outE().hasLabel("read").inV().is(resource1)).path().toList();
// q1 returns [] (which is expected)
q2 = graph.traversal().V(user2.id())
.repeat(__.out().simplePath())
.until(__.outE().hasLabel("write").inV().is(resource1)).path().toList();
// q2 returns [[v[2], v[3], v[4]]] (which seems right too)
你不应该遍历任意边(没有标签限制)。我想你正在寻找
- 直接连接到资源
- 从用户角色到资源的连接或
- 从任何父角色到资源的连接
在单个查询中涵盖所有三种情况的最佳方法是从用户开始,遍历所有 member
和 child_of
边,发出沿路径的所有顶点并最终检查是否从任何顶点到资源都有 read
/ write
连接:
gremlin> // Does User#1 have "read" permission on Resource#1? (it does not)
gremlin> g.V(1).emit().
repeat(out("member","child_of")).
out("read").has("name","resource_1").hasNext()
==>false
gremlin> // Does User#2 have "write" permission on Resource#1? (it does).
gremlin> g.V(2).emit().
repeat(out("member","child_of")).
out("write").has("name","resource_1").hasNext()
==>true
我有下图:
我正在使用 Tinkergraph 来尝试找出:
- 用户#1是否对资源#1具有"read"权限? (它没有)
- User#2 是否对 Resource#1 具有 "write" 权限? (确实如此)。
我还试图找到一个不特定于这个确切图形的查询,因为在现实生活模型中,它们之间可能存在多个层次角色。我刚刚开始掌握 Gremlin 语法,但我发现这个特定的查询难以捉摸。这是创建上图的代码:
Graph graph = TinkerGraph.open();
Vertex user1 = graph.addVertex(T.label, "user", T.id, 1, "name", "marko");
Vertex user2 = graph.addVertex(T.label, "user", T.id, 2, "name", "vadas");
Vertex role1 = graph.addVertex(T.label, "role", T.id, 3, "name", "role_1");
Vertex role2 = graph.addVertex(T.label, "role", T.id, 4, "name", "role_2");
Vertex resource1 = graph.addVertex(T.label, "resource", T.id, 5, "name", "resource_1");
Vertex resource2 = graph.addVertex(T.label, "resource", T.id, 6, "name", "resource_2");
user1.addEdge("read", resource2, T.id, 7);
user1.addEdge("member", role2, T.id, 8);
user2.addEdge("owns", resource2, T.id, 9);
user2.addEdge("member", role1, T.id, 10);
role1.addEdge("child_of", role2, T.id, 11);
role1.addEdge("read", resource1, T.id, 12);
role2.addEdge("write", resource1, T.id, 13);
role2.addEdge("write", resource2, T.id, 14);
我目前尝试回答问题 #1 是使用 repeat
,从 User#1 开始,然后沿着路径找到 "outEdge"标签 "read" 通向顶点 Resource#1.
啊哈,在我写这篇文章的时候,我可能刚刚弄明白了,但由于我是 Gremlin 的新手,也许熟悉 Gremlin 的人可以对其进行理智检查,或者告诉我是否有更好的方法?如果没有,那么也许这会对试图解决同样问题的其他人有所帮助。
q1 = graph.traversal().V(user1.id())
.repeat(__.out().simplePath())
.until(__.outE().hasLabel("read").inV().is(resource1)).path().toList();
// q1 returns [] (which is expected)
q2 = graph.traversal().V(user2.id())
.repeat(__.out().simplePath())
.until(__.outE().hasLabel("write").inV().is(resource1)).path().toList();
// q2 returns [[v[2], v[3], v[4]]] (which seems right too)
你不应该遍历任意边(没有标签限制)。我想你正在寻找
- 直接连接到资源
- 从用户角色到资源的连接或
- 从任何父角色到资源的连接
在单个查询中涵盖所有三种情况的最佳方法是从用户开始,遍历所有 member
和 child_of
边,发出沿路径的所有顶点并最终检查是否从任何顶点到资源都有 read
/ write
连接:
gremlin> // Does User#1 have "read" permission on Resource#1? (it does not)
gremlin> g.V(1).emit().
repeat(out("member","child_of")).
out("read").has("name","resource_1").hasNext()
==>false
gremlin> // Does User#2 have "write" permission on Resource#1? (it does).
gremlin> g.V(2).emit().
repeat(out("member","child_of")).
out("write").has("name","resource_1").hasNext()
==>true