From commits-return-37925-archive-asf-public=cust-asf.ponee.io@tinkerpop.apache.org Wed Oct 9 23:39:15 2019
Return-Path:
GraphComputer
(OLAP) based traversals.
gremlin> g = graph.traversal().withComputer()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], graphcomputer]
gremlin> g.V().pageRank().by('pageRank').values('pageRank')
-==>0.11375510357865541
-==>0.11375510357865541
==>0.3047200907912249
==>0.14598540152719106
==>0.14598540152719106
-==>0.17579889899708231
+==>0.17579889899708231
+==>0.11375510357865541
+==>0.11375510357865541
store()
:
It may seem simple, but the most obvious choice to modifying what is in a list is to simply unfold()
the List
:
List
result, but consider what happens when there is more than one:
List
traversers "locally" unfold()
the lists to transform them:
This pattern for unfolding and folding List
traversers ends up having other applications:
List
. For example, consider the following three traversals:
store()
to aid in construction of this List
:
union()
to
to end up with a Map
is with valueMap()
:
List
.
by avoiding use of valueMap()
:
valueMap()Map
instances with any sorts of values:
Map
:
Map
to be "nicer":
MapList
values within a Map
:
union()
reconstructed as a new Map
that has been merged together:
Map
group().
by(keys).
by(select(values).unfold())
-==>[id:1,degree:3,name:marko,label:person,age:29]
+==>[degree:3,name:marko,label:person,age:29,id:1]
List
back for all the val
List
instances when necessary:
List
back for all the val
unfold().
fold().
choose(count(local).is(eq(1)), unfold()))
-==>[id:1,name:marko,label:person,age:[29,100]]
+==>[name:marko,label:person,age:[29,100],id:1]
One way to detect the various subgraphs would be to do something like this:
GraphComputer
is forced to analyze far more paths):
.emit()
a Traverser before the repeat()-loop.
Gremlin can detect if such a cycle exists with:
One way to find the duplicate edges would be to do something like this:
Note that the above traversal could also be written using match
step:
gremlin> g.V(1).as("a").V(3).addE("created").property("weight",0.4d).from("a").iterate()
gremlin> g.V(1).as("a").V(3).addE("created").property("weight",0.5d).from("a").iterate()
gremlin> g.V(1).outE("created").valueMap(true)
-==>[id:9,weight:0.4,label:created]
-==>[id:13,weight:0.4,label:created]
-==>[id:14,weight:0.5,label:created]
+==>[weight:0.4,label:created,id:9]
+==>[weight:0.4,label:created,id:13]
+==>[weight:0.5,label:created,id:14]
To identify the duplicate with this revised definition, the previous traversal can be modified to:
Consider the following example with some duplicate vertices added to the "modern" graph:
Map
provided by the gremlin> g.V().has('name','marko').
outE().inV().
path().by('name').by(valueMap(true))
-==>[marko,[id:9,weight:0.4,label:created],lop]
-==>[marko,[id:7,weight:0.5,label:knows],vadas]
-==>[marko,[id:8,weight:1.0,label:knows],josh]
+==>[marko,[weight:0.4,label:created,id:9],lop]
+==>[marko,[weight:0.5,label:knows,id:7],vadas]
+==>[marko,[weight:1.0,label:knows,id:8],josh]
Checking for whether or not a graph element is present in the graph is simple:
This "get or create" logic can be expanded to be "upsert" like functionality as follows:
It is possible to do similar sorts of operations with edges using the same pattern:
Consider the following traversal over the "modern" toy graph:
coalesce
:
In Gremlin, a basic approach to paging would look something like the following:
The only way to completely avoid that problem is to re-use the same traversal instance:
The next step is to determine who else purchased those products:
Next, do some grouping to find count how many products they have in common:
The above output shows that one product is held in common making it the top recommendation:
Getting a list of all the movies that Alice’s friends like could be done like this: