用 project() 和 select() 在 Gremlin 中汇总路径信息
Summarize path information in Gremlin with project() and select()
我正在尝试编写一个 Gremlin 查询,它将遍历多个顶点和 return 叶子以及有关它到达那里所遵循的路径的一些信息。
举个例子最容易解释:
# Sample graph diagram
# 1 --> 2* --> 3* --> 4
# \ \---> 5* --> 6
# \-> 7
# Create sample graph
g.addV('V').as('1').property('id','1').property('notable',false)
.addV('V').as('2').property('id','2').property('notable',true)
.addE('E').from('1')
.addV('V').as('3').property('id','3').property('notable',true)
.addE('E').from('2')
.addV('V').as('4').property('id','4').property('notable',false)
.addE('E').from('3')
.addV('V').as('5').property('id','5').property('notable',true)
.addE('E').from('2')
.addV('V').as('6').property('id','6').property('notable',false)
.addE('E').from('5')
.addV('V').as('7').property('id','7').property('notable',false)
.addE('E').from('1')
以下遍历从顶点1开始,尽可能继续out()
,使用as()
.
收集"notable"个顶点
g.V('1')
.out()
.until(out().count().is(0))
.repeat(
optional(has('notable', true).as("notables"))
.out()
)
.project('Id','NotableAncestors')
.by(id())
.by(coalesce(
select('notables').unfold().id(), inject([])
))
我想看到的是每片叶子的 ID 及其 "notable" 祖先的 ID 数组:
[
{
"Id": "7",
"NotableAncestors": []
},
{
"Id": "4",
"NotableAncestors": ["2", "3"]
},
{
"Id": "6",
"NotableAncestors": ["2", "5"]
}
]
但是,我得到的不是 NotableAncestors
数组,而是第一个值,因为 unfold()
将数组展平为其中的第一项,如下所示。或者,如果我省略 unfold()
,我会得到一个数组,但它总是空的。
[
{
"Id": "7",
"NotableAncestors": []
},
{
"Id": "4",
"NotableAncestors": "2"
},
{
"Id": "6",
"NotableAncestors": "2"
}
]
我觉得你可以简化一下。首先请注意 as()
是一个步骤标签,您可以参考它来检查在遍历的特定点该步骤中有什么遍历器,所以它不是真正的 "collecting" 东西。这是另一种方法:
gremlin> g.V('1').
......1> repeat(out()).
......2> emit(outE().count().is(0)).
......3> project('Id','NotableAncestors').
......4> by(id()).
......5> by(path().unfold().has('notable',true).id().fold())
==>[Id:7,NotableAncestors:[]]
==>[Id:4,NotableAncestors:[2,3]]
==>[Id:6,NotableAncestors:[2,5]]
我删除了一堆额外的步骤,并简单地从顶点“1”开始反复遍历 out()
,只发出您关心的叶顶点。然后,我只是分析 path()
到达那个叶子的任何 "notable" 顶点,并将它们添加到 List
for "NotableAncestors"`.
我正在尝试编写一个 Gremlin 查询,它将遍历多个顶点和 return 叶子以及有关它到达那里所遵循的路径的一些信息。
举个例子最容易解释:
# Sample graph diagram
# 1 --> 2* --> 3* --> 4
# \ \---> 5* --> 6
# \-> 7
# Create sample graph
g.addV('V').as('1').property('id','1').property('notable',false)
.addV('V').as('2').property('id','2').property('notable',true)
.addE('E').from('1')
.addV('V').as('3').property('id','3').property('notable',true)
.addE('E').from('2')
.addV('V').as('4').property('id','4').property('notable',false)
.addE('E').from('3')
.addV('V').as('5').property('id','5').property('notable',true)
.addE('E').from('2')
.addV('V').as('6').property('id','6').property('notable',false)
.addE('E').from('5')
.addV('V').as('7').property('id','7').property('notable',false)
.addE('E').from('1')
以下遍历从顶点1开始,尽可能继续out()
,使用as()
.
g.V('1')
.out()
.until(out().count().is(0))
.repeat(
optional(has('notable', true).as("notables"))
.out()
)
.project('Id','NotableAncestors')
.by(id())
.by(coalesce(
select('notables').unfold().id(), inject([])
))
我想看到的是每片叶子的 ID 及其 "notable" 祖先的 ID 数组:
[
{
"Id": "7",
"NotableAncestors": []
},
{
"Id": "4",
"NotableAncestors": ["2", "3"]
},
{
"Id": "6",
"NotableAncestors": ["2", "5"]
}
]
但是,我得到的不是 NotableAncestors
数组,而是第一个值,因为 unfold()
将数组展平为其中的第一项,如下所示。或者,如果我省略 unfold()
,我会得到一个数组,但它总是空的。
[
{
"Id": "7",
"NotableAncestors": []
},
{
"Id": "4",
"NotableAncestors": "2"
},
{
"Id": "6",
"NotableAncestors": "2"
}
]
我觉得你可以简化一下。首先请注意 as()
是一个步骤标签,您可以参考它来检查在遍历的特定点该步骤中有什么遍历器,所以它不是真正的 "collecting" 东西。这是另一种方法:
gremlin> g.V('1').
......1> repeat(out()).
......2> emit(outE().count().is(0)).
......3> project('Id','NotableAncestors').
......4> by(id()).
......5> by(path().unfold().has('notable',true).id().fold())
==>[Id:7,NotableAncestors:[]]
==>[Id:4,NotableAncestors:[2,3]]
==>[Id:6,NotableAncestors:[2,5]]
我删除了一堆额外的步骤,并简单地从顶点“1”开始反复遍历 out()
,只发出您关心的叶顶点。然后,我只是分析 path()
到达那个叶子的任何 "notable" 顶点,并将它们添加到 List
for "NotableAncestors"`.