Я пытаюсь реализовать своего рода «оконную функцию» в запросе Gremlin: я хочу выделить все ребра, выходящие из вершины, которые имеют временную метку в течение 24 часов с момента последнего обновления (локально для вершины).
Например, если пользователь А получил доступ к следующим ресурсам:
- Ресурс 1 на 2019/04/02 23: 00
- Ресурс 2 на 2019/04/0201: 00
- Ресурс 3 в 2019/04/01 22: 00
.. тогда я бы хотел, чтобы запрос возвратил ресурсы 1 и 2 и пропустил ресурс 3, потому чтодоступ к нему был получен за 25 часов до последнего доступа пользователя А. (за пределами 24-часового окна).
Я пробовал несколько разных подходов, например, с использованием 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
.
Мне кажется, что я просто зациклен на семантике Гремлин - я пытаюсь сравнить значения в неправильной форме.Что мне нужно сделать, чтобы получить доступ к значению "windowStart" для текущей вершины в обходе в предикате gt / lt?