我有以下图表:
我正在使用Tinkergraph试图弄清楚:
我还试图找到一个不是特定于这个确切图形的查询,因为在现实生活模型中,它们之间可能存在多个层次结构角色。我刚刚开始掌握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
,从用户#1 开始,然后按照路径找到“outEdge”,标签为“read”,导致vertex 资源#1 。
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)
答案 0 :(得分:1)
你不应该遍历任意的边缘(没有标签限制)。我认为你正在寻找
在单个查询中覆盖所有三种情况的最佳方法是从用户开始,遍历所有member
和child_of
边,沿路径发出所有顶点并最终检查是否存在&# 39;从任何顶点到资源的sa 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