-
Notifications
You must be signed in to change notification settings - Fork 239
Except Retain Pattern
okram edited this page Jan 12, 2011
·
10 revisions
In many instances its desirable to traverse to only those elements that have not been seen in a previous step. Specific use cases are:
- “Who are my friends friends that are not already my friends?”
- “What is liked by the people that like the same things as me that I don’t already like?”
The solution to these types of problems is called the except pattern. Its opposite is the retain pattern—only traverse to those vertices that have been seen in a previous step.
gremlin> g.v(1).outE.inV
==>v[2]
==>v[3]
==>v[4]
gremlin> g.v(1).outE.inV.outE.inV
==>v[5]
==>v[3]
Both the first outE.inV
and the second emit v[3]
. To ensure that v[3]
is not traversed to on the second step, its necessary to save the results seen after the first outE.inV
.
gremlin> x = [] as Set
gremlin> g.v(1).outE.inV.gather._{x.addAll(it)}.scatter.outE.inV{!x.contains(it)}
==>v[5]
The
gather
step aggregates all the results up to that stage in the pipeline. Those results are stored in x
. The scatter
step emits the gathered individual objects. The closure at the end checks to make sure the vertex is not contained in x
.
Expressed in other ways.
gremlin> x = [] as Set
gremlin> g.v(1).outE.inV >> x; x._().outE.inV{!x.contains(it)}
==>v[5]
gremlin> x = [] as Set
gremlin> (g.v(1).outE.inV >> x)._().outE.inV{!x.contains(it)}
==>v[5]
Finally, this pattern is so common, that a high-level pipe called aggregate
is provided. This pipe, in essence, accomplishes the behavior of gather._{x.addAll(it)}.scatter
.
gremlin> x = [] as Set
gremlin> g.v(1).outE.inV.aggregate(x).outE.inV{!x.contains(it)}
==>v[5]