2

I'm asking nearly the same question as you see here, but with the constraint that the groovy, not java, syntax must be used. Ideally the answer to would be very concise.

I have a simple graph of people vertices. Each has an "age" property listing that person's age in years. There are also "worksFor" labeled edges connecting pairs of people vertices. I'd like to see all edges where the people at both ends of the edge have the same age property.

I'd then like a similar query where the two ages differ by less than 3 years.

As mentioned, this should be in groovy, not Java, syntax. Gremlin 3 is preferred, but Gremlin 2 answers are acceptable.

Community
  • 1
  • 1
user3624334
  • 479
  • 3
  • 12
  • ???. As mentioned, an answer to this class of problem already exists in Java so that would not be useful to this community. Gremlin 2 is deprecated by the TinkerPop community, so it would be less useful to this community than a G3 answer, but because G2 and G3 are so similar, it still would be of some value. – user3624334 Mar 17 '16 at 13:28
  • To be clearer, this is not just for my personal benefit. Someone came to me asking a similar question. And she asked me because someone was asking her. And the person asking her was asking on behalf of his customer.. Because none of us know how to solve this problem, it seems like a class of problem that would be valuable to answer, so I tried to come up with a simple version of the problem here that would be of benefit to all of us involved here as well to any others facing similar problems. – user3624334 Mar 17 '16 at 13:36

3 Answers3

7

all edges where the people at both ends of the edge have the same age property

g.V().as("a").outE("worksFor").as("e").inV().as("b").select("a","b").by("age").
      where("a", eq("b")).select("e")

where the two ages differ by less than 3 years

g.V().as("a").outE("worksFor").as("e").inV().as("b").select("a","b").by("age").
      filter {Math.abs(it.get().get("a") - it.get().get("b")) < 3}.select("e")
Daniel Kuppitz
  • 10,846
  • 1
  • 25
  • 34
  • That's a great answer. I was about to post one, but yours is better than what I would have posted. I will add two comments to what you've provided though. (1) Both half of the answer work well in TinkerPop3/Gremlin3. The Gremlin docs do suggest that one try to avoid lambdas like seen in the filter operation above, but I have not found a better option. (2) Another approach for the second half of the problem is to start with the list of edges: `g.E().hasLabel("worksFor").filter{ Math.abs(it.get().outVertex().value('age')-it.get().inVertex().value('age')) < 3 }` – user3624334 Mar 17 '16 at 17:50
  • I never use lambdas unless there's really no other solution. I would expect your `g.E()...` query to be significantly slower than mine. You should measure the performance of both queries over your graph. – Daniel Kuppitz Mar 17 '16 at 21:37
1

If we know the target vertex against which all other vertices are compared, the following may work:

t=g.V().has('id', 'target_node_id').values('age').next()

g.V().has('age').filter{it.get().value('age')-t<=3 && it.get().value('age')-t>=-3}

I don't know how to do it in one query. I also don't know if there is a function/step to get the absolute value.

This only partially satisfies your need, but it may be a start.

Long Hill
  • 11
  • 1
0

Comparing two date properties using math step:

g.V().hasLabel('EnterExitDate').limit(10000).as('enter','exit')
    .where("enter",lt("exit")).by('enter').by('exit')
    .where(math('(exit - enter) / (3600*1000) ')
        .by(values('exit').map({ it.get().time }))
        .by(values('enter').map({ it.get().time }))
        .is(lt(1)))
    .valueMap()

This query will find all pairs of enter-exit record of employees that have happened within 1 hour.

EnterExitDate class:

public class EnterExitDate {
    private Date enter;
    private Date exit;
    // getters and setters...
}
youhans
  • 6,101
  • 4
  • 27
  • 39