在Gremlin中将属性值与汇总值进行比较

时间:2019-04-09 18:31:39

标签: graph-databases gremlin tinkerpop

我正在尝试在Gremlin查询中实现某种“窗口函数”:我想选择离开顶点的所有边,这些边在上次更新后24小时内(对顶点本地)具有时间戳。

例如,如果用户A访问了以下资源:

  • 资源1在2019/04/02 23:00
  • 资源2在2019/04/02 01:00
  • 资源3在2019/04/01 22:00

..然后,我希望查询返回资源1和2,并省略资源3,因为它是在用户A的最新访问之前25小时(在24小时窗口之外)访问的。

我尝试了几种不同的方法,例如使用localaggregate

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”值?

1 个答案:

答案 0 :(得分:1)

我对我的评论的答案做了一些假设。以下查询将为您提供最近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")