用于查找重复的复杂非线性模式的 Gremlin 查询
Gremlin query for finding repeating complex non-linear patterns
我正在尝试找出如何匹配非线性 pattern/blueprint 的重复实例,如下例用例所示:
顶点类型(每个都有 属性 "name"):
- 用户
- 关系
- 角色
- 角色类型
边类型(没有任何属性)
- InRelation,从用户到关系
- OwnsRole,从用户到角色
- HasRole,从关系到角色
- IsOfType,从角色到角色类型
我正在考虑的用户 UX 和用户 UY 之间的 complex repeating pattern 是 5 个必需关系的组合:
- 用户 UX 与关系 RE 相关
- 用户 UY 与关系 RE 相关(UY != UX)
- 用户 UX OwnsRole 角色 RO
- 关系 RE HasRole 角色 RO
- 角色 RO IsOfType 角色类型 RT
具体来说,用RT一个特定的右顶点,比如名字为"Child"的顶点,这样整个模式的意思就变成用户UX与用户UY有关系,用户UX定义了他们分配给他们与用户 UY 的关系 RE 的角色 RO,并且他们给了角色类型 "Child".
例如OrientDB 的 SQL 方言使用他们的 MATCH 语法,可以使用以下语句找到此模式的所有单独匹配项:
SELECT ux.name, uy.name FROM (
MATCH
{class: User, as: ux} -InRelation-> {class: Relation, as: re} <-InRelation- {class: User, as: uy, where: ($matched.ux != $currentMatch)},
{class: User, as: ux} -OwnsRole-> {class: Role, as: ro} <-HasRole- {class: Relation, as: re},
{class: Role, as: ro} -HasType-> {class: RoleType, as: rt, where: (name = 'Child')}
RETURN ux, re, uy, ro, rt).
在Neo4j的CypherQL中,可以构造类似的语句。
我还没有设法写出等效的 Gremlin 查询(主要是因为使用 Back() 子句似乎弄乱了我的遍历),但我知道一旦我设法这样做,重写它以便它可以找到模式的重复实例应该是可行的。
所以:给定 this graph,我如何编写一个
的 gremlin 查询
- 找到名称为 'jim' 的用户顶点的所有直接子节点(即名称为 'jeff' 的用户顶点?
- 找到名称为 'jim' 的用户顶点的所有直接和间接子节点(即名称为 'jeff'、'jill' 和 'john' 的用户顶点)?
重建示例图的一些 Gremlin 语句会有所帮助,但这是我的猜测:
g.V().hasLabel("User").match(
__.as("ux").out("InRelation").as("re"),
__.as("re").in("InRelation").as("uy"),
__.as("ux").out("OwnsRole").as("ro"),
__.as("re").out("OwnsRole").as("ro"),
__.as("ro").out("HasType").has("name", "Child")).
where("ux", neq("uy")).
select("ux","uy").by("name")
但是,正如 Stephen 在他的评论中指出的那样,您似乎在使用 Gremlin 2。我的遍历是针对 Gremlin 3 的(但老实说,我并不真正了解任何图形数据库,它仍在使用 TinkerPop 2).
我正在尝试找出如何匹配非线性 pattern/blueprint 的重复实例,如下例用例所示:
顶点类型(每个都有 属性 "name"):
- 用户
- 关系
- 角色
- 角色类型
边类型(没有任何属性)
- InRelation,从用户到关系
- OwnsRole,从用户到角色
- HasRole,从关系到角色
- IsOfType,从角色到角色类型
我正在考虑的用户 UX 和用户 UY 之间的 complex repeating pattern 是 5 个必需关系的组合:
- 用户 UX 与关系 RE 相关
- 用户 UY 与关系 RE 相关(UY != UX)
- 用户 UX OwnsRole 角色 RO
- 关系 RE HasRole 角色 RO
- 角色 RO IsOfType 角色类型 RT
具体来说,用RT一个特定的右顶点,比如名字为"Child"的顶点,这样整个模式的意思就变成用户UX与用户UY有关系,用户UX定义了他们分配给他们与用户 UY 的关系 RE 的角色 RO,并且他们给了角色类型 "Child".
例如OrientDB 的 SQL 方言使用他们的 MATCH 语法,可以使用以下语句找到此模式的所有单独匹配项:
SELECT ux.name, uy.name FROM (
MATCH
{class: User, as: ux} -InRelation-> {class: Relation, as: re} <-InRelation- {class: User, as: uy, where: ($matched.ux != $currentMatch)},
{class: User, as: ux} -OwnsRole-> {class: Role, as: ro} <-HasRole- {class: Relation, as: re},
{class: Role, as: ro} -HasType-> {class: RoleType, as: rt, where: (name = 'Child')}
RETURN ux, re, uy, ro, rt).
在Neo4j的CypherQL中,可以构造类似的语句。
我还没有设法写出等效的 Gremlin 查询(主要是因为使用 Back() 子句似乎弄乱了我的遍历),但我知道一旦我设法这样做,重写它以便它可以找到模式的重复实例应该是可行的。
所以:给定 this graph,我如何编写一个
的 gremlin 查询- 找到名称为 'jim' 的用户顶点的所有直接子节点(即名称为 'jeff' 的用户顶点?
- 找到名称为 'jim' 的用户顶点的所有直接和间接子节点(即名称为 'jeff'、'jill' 和 'john' 的用户顶点)?
重建示例图的一些 Gremlin 语句会有所帮助,但这是我的猜测:
g.V().hasLabel("User").match(
__.as("ux").out("InRelation").as("re"),
__.as("re").in("InRelation").as("uy"),
__.as("ux").out("OwnsRole").as("ro"),
__.as("re").out("OwnsRole").as("ro"),
__.as("ro").out("HasType").has("name", "Child")).
where("ux", neq("uy")).
select("ux","uy").by("name")
但是,正如 Stephen 在他的评论中指出的那样,您似乎在使用 Gremlin 2。我的遍历是针对 Gremlin 3 的(但老实说,我并不真正了解任何图形数据库,它仍在使用 TinkerPop 2).