When working with Apache TinkerPop and its graph traversal language Gremlin, one of the most common beginner mistakes is forgetting to terminate the traversal before assigning it to a variable. Let's use following domain model to demo this.
1. E-Commerce Domain Model Overview
To demonstrate the example, we will use a simple e-commerce domain model built using an in-memory TinkerGraph. This model is intentionally small but expressive enough to showcase real-world traversal patterns.
At a high level, the graph represents:
· Customers placing orders
· Orders containing products
· Products belonging to categories
· Orders being delivered to cities
This gives us multiple vertex labels, relationships, and property types to work with and ideal for exploring how valueMap() behaves across different scenarios.
Vertex Types
· City: Represents delivery locations
· Category: Represents product categories
· Product: Represents items that can be purchased
· Customer: Represents users of the platform
· Order: Represents purchase transactions
Each vertex label has a small and focused set of properties, which makes it easier to see how valueMap() returns property data and how WithOptions affects the output.
Edge Types and Relationships
· belongsTo: Connects a product to its category
· placed: Connects a customer to an order
· contains: Connects an order to one or more product vertices. An order may contain multiple products
· deliveredTo: Connects an order to a city, represents the delivery destination for the order
Gremlin Code 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()
gremlin> g.V().valueMap(true) ==>[id:0,label:city,name:[Bengaluru]] ==>[id:33,label:customer,customerId:[C102],name:[Priya Iyer]] ==>[id:2,label:city,name:[Hyderabad]] ==>[id:4,label:city,name:[Chennai]] ==>[id:36,label:customer,customerId:[C103],name:[Rohit Verma]] ==>[id:6,label:city,name:[Pune]] ==>[id:39,label:order,orderId:[O9001]] ==>[id:8,label:category,name:[Electronics]] ==>[id:41,label:order,orderId:[O9002]] ==>[id:10,label:category,name:[Books]] ==>[id:43,label:order,orderId:[O9003]] ==>[id:12,label:category,name:[Clothing]] ==>[id:45,label:order,orderId:[O9004]] ==>[id:14,label:product,name:[Laptop],sku:[P1001]] ==>[id:47,label:order,orderId:[O9005]] ==>[id:17,label:product,name:[Smartphone],sku:[P1002]] ==>[id:20,label:product,name:[Java Programming Book],sku:[P2001]] ==>[id:23,label:product,name:[T-Shirt],sku:[P3001]] ==>[id:30,label:customer,customerId:[C101],name:[Amit Sharma]] gremlin> gremlin> gremlin> g.E().valueMap(true) ==>[id:64,label:deliveredTo] ==>[id:65,label:deliveredTo] ==>[id:49,label:placed] ==>[id:50,label:placed] ==>[id:51,label:placed] ==>[id:52,label:placed] ==>[id:53,label:placed] ==>[id:54,label:contains] ==>[id:55,label:contains] ==>[id:56,label:contains] ==>[id:57,label:contains] ==>[id:26,label:belongsTo] ==>[id:58,label:contains] ==>[id:27,label:belongsTo] ==>[id:59,label:contains] ==>[id:28,label:belongsTo] ==>[id:60,label:contains] ==>[id:29,label:belongsTo] ==>[id:61,label:deliveredTo] ==>[id:62,label:deliveredTo] ==>[id:63,label:deliveredTo]
Use Case 1: Get All Orders Delivered to Bengaluru
orders = g.V(). hasLabel('city'). has('name', 'Bengaluru'). in('deliveredTo')
Above snippet stores the traversal in orders variable, not the result
gremlin> orders = g.V(). ......1> hasLabel('city'). ......2> has('name', 'Bengaluru'). ......3> in('deliveredTo') ==>v[39] ==>v[41] gremlin> gremlin> orders gremlin> gremlin> orders.getClass() ==>class org.apache.tinkerpop.gremlin.groovy.loaders.SugarLoader$GraphTraversalCategory
To store the correct result we need to terminate the traversal.
orders = g.V(). hasLabel('city'). has('name', 'Bengaluru'). in('deliveredTo'). toList()
gremlin> orders = g.V(). ......1> hasLabel('city'). ......2> has('name', 'Bengaluru'). ......3> in('deliveredTo'). ......4> toList() ==>v[39] ==>v[41] gremlin> gremlin> orders ==>v[39] ==>v[41] gremlin> gremlin> orders.getClass() ==>class java.util.ArrayList
We can print each order details with the traversal.
orders.each { println g.V(it).valueMap(true).next() }
gremlin> orders.each { ......1> println g.V(it).valueMap(true).next() ......2> } [id:39, label:order, orderId:[O9001]] [id:41, label:order, orderId:[O9002]]
Use Case 2: Print Products Ordered by Amit Sharma
Let's get 'Amit Sharma' vertex.
amit = g.V(). hasLabel('customer'). has('name', 'Amit Sharma'). next()
Get the orders by Amit Sharma.
amitOrders = g.V(amit). out('placed'). toList()
Print the orders details.
amitOrders.each { println g.V(it).valueMap(true).next() }
gremlin> amit = g.V(). ......1> hasLabel('customer'). ......2> has('name', 'Amit Sharma'). ......3> next() ==>v[30] gremlin> gremlin> amitOrders = g.V(amit). ......1> out('placed'). ......2> toList() ==>v[39] ==>v[41] gremlin> gremlin> gremlin> amitOrders.each { ......1> println g.V(it).valueMap(true).next() ......2> } [id:39, label:order, orderId:[O9001]] [id:41, label:order, orderId:[O9002]] ==>v[39] ==>v[41]
Print Orders with Products Inside Them.
amitOrders.each { order -> { println "Order: " + order.value('orderId') g.V(order). out('contains'). values('name'). toList(). each { println " Product: " + it } } }
gremlin> amitOrders.each { order -> { ......1> println "Order: " + order.value('orderId') ......2> ......2> g.V(order). ......3> out('contains'). ......4> values('name'). ......5> toList(). ......6> each { println " Product: " + it } ......7> } ......8> } Order: O9001 Product: Laptop Product: Java Programming Book Order: O9002 Product: Smartphone ==>v[39] ==>v[41]
Use Case 3: Get First 2 Products Only
next(2) return 2 elements in the traversal, next(n) will return the n elements in the traversal.
first2Products = g.V(). hasLabel('product'). next(2) first2Products.each {product -> { println product.value('name') }}
gremlin> first2Products = g.V(). ......1> hasLabel('product'). ......2> next(2) ==>v[14] ==>v[17] gremlin> gremlin> first2Products.each {product -> { ......1> println product.value('name') ......2> }} Laptop Smartphone ==>v[14] ==>v[17]
In the Gremlin Console, you can view all currently defined variables by running the command ":show variables".
Previous Next Home
No comments:
Post a Comment