gremlin sideEffect 的替代方案,因为 Neptune 不支持它?
Alternative for gremlin sideEffect since Neptune doesn't support it?
在 AWS Neptune 中,我正在尝试通过计算余弦相似度来创建用户顶点之间的相似度边,如 Daniel Kuppitz here -- https://gist.github.com/dkuppitz/79e0b009f0c9ae87db5a#file-cosim-groovy-L368 所述——gremlin 的 sideEffect 提供了一个有用的闭包,它允许进行一些数学计算以获得相似度分数并将此值写入每个 'similarity' 边。唉,Neptune 不支持 sideEffect。我正在寻找一种在不使用 sideEffect 的情况下在单个 gremlin 查询中 运行 下面示例中的注释部分的方法。感谢您的帮助!
g.V().match(
__.as("u1").outE("rated").as("r1"),
__.as("r1").inV().as("m"),
__.as("m").inE("rated").as("r2"),
__.as("r2").outV().as("u2")
).where("u1", neq("u2")).
group().by(select("u1","u2")).
by(select("r1","r2").by("rating")).
unfold().
as("kv").
select(keys).
addE("similarity").from("u1").to("u2").as("e").
// sideEffect {
// def r = it.get("kv").getValue()
// def xyDotProduct = r.collect {it.r1*it.r2}.sum()
// def xLength = Math.sqrt(r.collect {it.r1*it.r1}.sum())
// def yLength = Math.sqrt(r.collect {it.r2*it.r2}.sum())
// def similarity = xyDotProduct / (xLength * yLength)
// it.get().property("similarity", similarity)
// }.iterate()
Amazon Neptune 支持 sideEffect
步骤,但不支持对任何步骤使用 Groovy 闭包。我相信使用 math
和 project
步骤的组合可能会实现示例中显示的相同效果。这是一个 link 与 Haversine Greater Circle 距离有点相似(在复杂性方面)的计算。也许您可以使用类似于 this one from Practical Gremlin.
的方法
start = 'SFO'
stop = 'NRT'
g.withSideEffect("rdeg", 0.017453293).
withSideEffect("gcmiles",3956).
V().has('code',start).as('src').
V().has('code',stop).as('dst').
select('src','dst').
by(project('lat','lon').
by('lat').
by('lon')).
as('grp').
project('ladiff','lgdiff','lat1','lon1','lat2','lon2').
by(project('la1','la2').
by(select('grp').select('src').select('lat')).
by(select('grp').select('dst').select('lat')).
math('(la2 - la1) * rdeg')).
by(project('lg1','lg2').
by(select('grp').select('src').select('lon')).
by(select('grp').select('dst').select('lon')).
math('(lg2 - lg1) * rdeg')).
by(select('grp').select('src').select('lat')).
by(select('grp').select('src').select('lon')).
by(select('grp').select('dst').select('lat')).
by(select('grp').select('dst').select('lon')).
math('(sin(ladiff/2))^2 + cos(lat1*rdeg) * cos(lat2*rdeg) * (sin(lgdiff/2))^2').
math('gcmiles * (2 * asin(sqrt(_)))')
这种方法不是在闭包内使用变量,而是使用 project
有效地创建仍然可以传递给 math
步骤的相同变量。
在 AWS Neptune 中,我正在尝试通过计算余弦相似度来创建用户顶点之间的相似度边,如 Daniel Kuppitz here -- https://gist.github.com/dkuppitz/79e0b009f0c9ae87db5a#file-cosim-groovy-L368 所述——gremlin 的 sideEffect 提供了一个有用的闭包,它允许进行一些数学计算以获得相似度分数并将此值写入每个 'similarity' 边。唉,Neptune 不支持 sideEffect。我正在寻找一种在不使用 sideEffect 的情况下在单个 gremlin 查询中 运行 下面示例中的注释部分的方法。感谢您的帮助!
g.V().match(
__.as("u1").outE("rated").as("r1"),
__.as("r1").inV().as("m"),
__.as("m").inE("rated").as("r2"),
__.as("r2").outV().as("u2")
).where("u1", neq("u2")).
group().by(select("u1","u2")).
by(select("r1","r2").by("rating")).
unfold().
as("kv").
select(keys).
addE("similarity").from("u1").to("u2").as("e").
// sideEffect {
// def r = it.get("kv").getValue()
// def xyDotProduct = r.collect {it.r1*it.r2}.sum()
// def xLength = Math.sqrt(r.collect {it.r1*it.r1}.sum())
// def yLength = Math.sqrt(r.collect {it.r2*it.r2}.sum())
// def similarity = xyDotProduct / (xLength * yLength)
// it.get().property("similarity", similarity)
// }.iterate()
Amazon Neptune 支持 sideEffect
步骤,但不支持对任何步骤使用 Groovy 闭包。我相信使用 math
和 project
步骤的组合可能会实现示例中显示的相同效果。这是一个 link 与 Haversine Greater Circle 距离有点相似(在复杂性方面)的计算。也许您可以使用类似于 this one from Practical Gremlin.
start = 'SFO'
stop = 'NRT'
g.withSideEffect("rdeg", 0.017453293).
withSideEffect("gcmiles",3956).
V().has('code',start).as('src').
V().has('code',stop).as('dst').
select('src','dst').
by(project('lat','lon').
by('lat').
by('lon')).
as('grp').
project('ladiff','lgdiff','lat1','lon1','lat2','lon2').
by(project('la1','la2').
by(select('grp').select('src').select('lat')).
by(select('grp').select('dst').select('lat')).
math('(la2 - la1) * rdeg')).
by(project('lg1','lg2').
by(select('grp').select('src').select('lon')).
by(select('grp').select('dst').select('lon')).
math('(lg2 - lg1) * rdeg')).
by(select('grp').select('src').select('lat')).
by(select('grp').select('src').select('lon')).
by(select('grp').select('dst').select('lat')).
by(select('grp').select('dst').select('lon')).
math('(sin(ladiff/2))^2 + cos(lat1*rdeg) * cos(lat2*rdeg) * (sin(lgdiff/2))^2').
math('gcmiles * (2 * asin(sqrt(_)))')
这种方法不是在闭包内使用变量,而是使用 project
有效地创建仍然可以传递给 math
步骤的相同变量。