Thursday, 14 May 2026

Incoming Edge Traversals (inE()): Working with Incoming Incident Edges

  

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