So far, traversal steps have moved in two broad directions:
· Vertex: Edge using outE(), inE(), and bothE()
· Edge: Vertex using inV(), outV(), and bothV()
This chapter focuses on outV(), a step that is used only when the traversal is currently positioned on edges. Understanding outV() requires a clear grasp of what an out-vertex is.
What Is an Outgoing Vertex?
For a directed edge:
a ---> b
· a is the out-vertex
· b is the in-vertex
The edge originates from a and points to b. The outV() step always returns the vertex from which the edge starts.
Relationship to Other Steps
|
Step |
Meaning |
|
outE() |
Vertex → outgoing edges |
|
inE() |
Vertex → incoming edges |
|
bothE() |
Vertex → all incident edges |
|
outV() |
Edge → source vertex |
|
inV() |
Edge → target vertex |
|
bothV() |
Edge → both endpoints |
Example: An E-Commerce Graph
To make the discussion concrete, consider an e-commerce domain modeled as a property graph. The graph contains:
Vertex Types
· city: Bengaluru, Hyderabad, Chennai, Pune
· category: Electronics, Books, Clothing
· product: Laptop, Smartphone, Java Programming Book, T-Shirt
· customer: Amit Sharma, Priya Iyer, Rohit Verma
· order: O9001 to O9005
Edge Types
· belongsTo: product → category
· placed: customer → order
· contains: order → product
· deliveredTo: order → city
Each edge has a clear semantic direction that aligns with real-world meaning.
Gremlin Statements to build the Graph
graph = TinkerGraph.open() g = graph.traversal() blr = g.addV('city').property('name', 'Bengaluru').next() hyd = g.addV('city').property('name', 'Hyderabad').next() chn = g.addV('city').property('name', 'Chennai').next() pne = g.addV('city').property('name', 'Pune').next() catElectronics = g.addV('category').property('name', 'Electronics').next() catBooks = g.addV('category').property('name', 'Books').next() catClothing = g.addV('category').property('name', 'Clothing').next() p1 = g.addV('product').property('sku', 'P1001').property('name', 'Laptop').next() p2 = g.addV('product').property('sku', 'P1002').property('name', 'Smartphone').next() p3 = g.addV('product').property('sku', 'P2001').property('name', 'Java Programming Book').next() p4 = g.addV('product').property('sku', 'P3001').property('name', 'T-Shirt').next() g.V(p1).addE('belongsTo').to(catElectronics).next() g.V(p2).addE('belongsTo').to(catElectronics).next() g.V(p3).addE('belongsTo').to(catBooks).next() g.V(p4).addE('belongsTo').to(catClothing).next() c1 = g.addV('customer').property('customerId', 'C101').property('name', 'Amit Sharma').next() c2 = g.addV('customer').property('customerId', 'C102').property('name', 'Priya Iyer').next() c3 = g.addV('customer').property('customerId', 'C103').property('name', 'Rohit Verma').next() o1 = g.addV('order').property('orderId', 'O9001').next() o2 = g.addV('order').property('orderId', 'O9002').next() o3 = g.addV('order').property('orderId', 'O9003').next() o4 = g.addV('order').property('orderId', 'O9004').next() o5 = g.addV('order').property('orderId', 'O9005').next() g.V(c1).addE('placed').to(o1).next() g.V(c1).addE('placed').to(o2).next() g.V(c2).addE('placed').to(o3).next() g.V(c3).addE('placed').to(o4).next() g.V(c3).addE('placed').to(o5).next() g.V(o1).addE('contains').to(p1).next() g.V(o1).addE('contains').to(p3).next() g.V(o2).addE('contains').to(p2).next() g.V(o3).addE('contains').to(p4).next() g.V(o4).addE('contains').to(p1).next() g.V(o4).addE('contains').to(p4).next() g.V(o5).addE('contains').to(p3).next() g.V(o1).addE('deliveredTo').to(blr).next() g.V(o2).addE('deliveredTo').to(blr).next() g.V(o3).addE('deliveredTo').to(hyd).next() g.V(o4).addE('deliveredTo').to(chn).next() g.V(o5).addE('deliveredTo').to(pne).next()
From the established domain model:
· order ──contains──▶ product
· customer ──placed──▶ order
· order ──deliveredTo──▶ city
· product ──belongsTo──▶ category
This implies:
· Products have incoming contains edges
· Orders have incoming placed edges
· Cities have incoming deliveredTo edges
· Categories have incoming belongsTo edges
Example 1: Who Placed an Order?
To identify the customer who placed order O9003.
g.V(). has('order', 'orderId', 'O9003'). inE('placed'). outV(). valueMap(true)
inE('placed').outV() can be replaced using in('placed') step as well.
in('placed') = inE('placed').outV()
g.V(). has('order', 'orderId', 'O9003'). in('placed'). valueMap(true)
gremlin> g.V(). ......1> has('order', 'orderId', 'O9003'). ......2> inE('placed'). ......3> outV(). ......4> valueMap(true) ==>[id:33,label:customer,customerId:[C102],name:[Priya Iyer]] gremlin> gremlin> g.V(). ......1> has('order', 'orderId', 'O9003'). ......2> in('placed'). ......3> valueMap(true) ==>[id:33,label:customer,customerId:[C102],name:[Priya Iyer]]
Example 2: Orders That Reference a Product (Source Perspective)
To find which orders include the product Laptop.
g.V(). has('product', 'name', 'Laptop'). inE('contains'). outV(). valueMap(true)
gremlin> g.V(). ......1> has('product', 'name', 'Laptop'). ......2> inE('contains'). ......3> outV(). ......4> valueMap(true) ==>[id:39,label:order,orderId:[O9001]] ==>[id:45,label:order,orderId:[O9004]]
outV() vs inV()
|
Question |
Step |
|
Who initiated this relationship? |
outV() |
|
Who received this relationship? |
inV() |
In summary,
· outV() moves from an edge to its source vertex
· It returns the out-vertex of the edge
· Can only be used when traversing edges
· Naturally pairs with inE() and outE()
· Essential for understanding causality and ownership in graphs
Mastering outV() completes one half of the edge-to-vertex traversal model, enabling precise, readable Gremlin queries that reason explicitly about where relationships originate.
Previous Next Home
No comments:
Post a Comment