In earlier sections, traversal steps such as out(), in(), both(), and outE() introduced different ways to navigate a graph based on direction and element type (vertex vs. edge). The natural next step is to complete this picture by examining incoming incident edges.
Many real-world questions are not about where a vertex points, but about what points to it.
Examples include:
· Which orders reference this product?
· Who initiated relationships with this entity?
· What events led to this state?
· These questions are answered using the inE() step.
Incoming Incident Edges
An edge is incident to a vertex if it is connected to that vertex. If the vertex is the in-vertex of an edge, that edge is an incoming incident edge. Such edges terminate at the current vertex
Graphically:
a ---> b
From the perspective of vertex b:
· The edge is incoming
· The edge is incident to b
· a is the out-vertex, b is the in-vertex
The inE() step performs the following operation:
· Start at the current vertex
· Select all edges for which the vertex is the in-vertex
· Emit those edges as traversal results
Formally, inE() returns all incoming incident edges of the current vertex. Just like outE(), this step returns edges, not vertices.
Filtering by Edge Label
The inE() step supports filtering by edge labels:
· inE() → all incoming edges
· inE('contains') → incoming edges labeled contains
· inE('placed', 'contains') → multiple labels
This allows precise control when a vertex participates in multiple relationships.
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
These are exactly the situations where inE() is useful.
Example 1: Incoming Edges to a Product
To retrieve all relationships that reference a product.
g.V(). has('product', 'name', 'Laptop'). inE(). valueMap(true)
gremlin> g.V(). ......1> has('product', 'name', 'Laptop'). ......2> inE(). ......3> valueMap(true) ==>[id:54,label:contains] ==>[id:58,label:contains]
Example 2: Who Placed an Order?
Orders receive placed edges from customers.
g.V(). has('order', 'orderId', 'O9003'). inE('placed'). outV(). 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]]
You can achieve the sme behavior by executing below statement.
g.V(). has('order', 'orderId', 'O9003'). in('placed'). valueMap(true)
inE() vs in()
|
Requirement |
Recommended Step |
|
Only need source vertices |
in() |
|
Need edge properties |
inE() |
|
Filter or count relationships |
inE() |
|
Analyze incoming events |
inE() |
In summary,
· Incoming incident edges terminate at the current vertex
· inE() traverses from vertices to incoming edges
· Essential for inspecting and analyzing relationships
· Naturally pairs with outV()
· Complements outE() and completes edge-level traversal semantics
With outE() and inE(), Gremlin provides full control over edge-centric traversal, enabling precise, expressive graph queries that treat relationships as first-class data elements.
Previous Next Home
No comments:
Post a Comment