将 属性 值与 Gremlin 中的聚合值进行比较
Compare a property value to an aggregated value in Gremlin
我正在尝试在 Gremlin 查询中实现一种 "window function":我想 select 所有离开顶点的边,其时间戳在上次更新后的 24 小时内(局部于顶点)。
例如,如果用户 A 访问了以下资源:
- 资源 1 于 2019/04/02 23:00
- 2019 年 4 月 2 日的资源 2 01:00
- 2019 年 4 月 1 日的资源 3 22:00
.. 然后我希望查询 return 资源 1 和 2,并省略资源 3,因为它是在用户 A 的最新访问之前 25 小时访问的(在 24 小时 window).
我尝试了几种不同的方法,例如使用 local
和 aggregate
:
g.V()
.hasLabel(VertexLabel.User)
.local(__.outE(EdgeLabel.Accesses) // I also tried "sideEffect" here
.values(EdgeProperties.UpdateTime).max().math("_ - 24*60*60*1000")
.aggregate("windowStart"))
.where(
__.outE(EdgeLabel.Accesses)
.has(EdgeProperties.UpdateTime, P.gt("windowStart"))
)
这个特定的例子给我错误 ClassCastException: java.lang.Double cannot be cast to org.apache.tinkerpop.gremlin.structure.Element
。
并且还使用 sack
:
g.V()
.hasLabel(VertexLabel.User)
.sack(Operator.assign).by(
__.outE(EdgeLabel.Accesses).values(EdgeProperties.UpdateTime).max())
.sack(Operator.minus).by(__.constant(24*60*60*1000)
.where(
__.outE(EdgeLabel.Accesses)
.not(__.sack().is(P.gt(__.values(EdgeProperties.UpdateTime))))
)
这给我错误 ClassCastException: org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal cannot be cast to java.lang.Long
。
我觉得我只是被 Gremlin 语义挂断了——我正在尝试以错误的形式比较值。我需要做什么才能在 gt/lt 谓词中访问遍历中当前顶点的 "windowStart" 值?
我对我的评论的答案可能做了一些假设。以下查询会给出最近24小时内的每个用户及其各自访问的资源(参考时间为最后一次访问资源的时间):
g.V().hasLabel(VertexLabel.User).
match(__.as("user").map(outE(EdgeLabel.Accesses).
values(EdgeProperties.UpdateTime).max()).
math("_-24*60*60*1000").as("m"),
__.as("user").outE(EdgeLabel.Accesses).
where(gt("m")).
by(EdgeProperties.UpdateTime).
by().
inV().fold().as("resources")).
select("user","resources")
我正在尝试在 Gremlin 查询中实现一种 "window function":我想 select 所有离开顶点的边,其时间戳在上次更新后的 24 小时内(局部于顶点)。
例如,如果用户 A 访问了以下资源:
- 资源 1 于 2019/04/02 23:00
- 2019 年 4 月 2 日的资源 2 01:00
- 2019 年 4 月 1 日的资源 3 22:00
.. 然后我希望查询 return 资源 1 和 2,并省略资源 3,因为它是在用户 A 的最新访问之前 25 小时访问的(在 24 小时 window).
我尝试了几种不同的方法,例如使用 local
和 aggregate
:
g.V()
.hasLabel(VertexLabel.User)
.local(__.outE(EdgeLabel.Accesses) // I also tried "sideEffect" here
.values(EdgeProperties.UpdateTime).max().math("_ - 24*60*60*1000")
.aggregate("windowStart"))
.where(
__.outE(EdgeLabel.Accesses)
.has(EdgeProperties.UpdateTime, P.gt("windowStart"))
)
这个特定的例子给我错误 ClassCastException: java.lang.Double cannot be cast to org.apache.tinkerpop.gremlin.structure.Element
。
并且还使用 sack
:
g.V()
.hasLabel(VertexLabel.User)
.sack(Operator.assign).by(
__.outE(EdgeLabel.Accesses).values(EdgeProperties.UpdateTime).max())
.sack(Operator.minus).by(__.constant(24*60*60*1000)
.where(
__.outE(EdgeLabel.Accesses)
.not(__.sack().is(P.gt(__.values(EdgeProperties.UpdateTime))))
)
这给我错误 ClassCastException: org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal cannot be cast to java.lang.Long
。
我觉得我只是被 Gremlin 语义挂断了——我正在尝试以错误的形式比较值。我需要做什么才能在 gt/lt 谓词中访问遍历中当前顶点的 "windowStart" 值?
我对我的评论的答案可能做了一些假设。以下查询会给出最近24小时内的每个用户及其各自访问的资源(参考时间为最后一次访问资源的时间):
g.V().hasLabel(VertexLabel.User).
match(__.as("user").map(outE(EdgeLabel.Accesses).
values(EdgeProperties.UpdateTime).max()).
math("_-24*60*60*1000").as("m"),
__.as("user").outE(EdgeLabel.Accesses).
where(gt("m")).
by(EdgeProperties.UpdateTime).
by().
inV().fold().as("resources")).
select("user","resources")