SlideShare a Scribd company logo
1 of 21
Neo4J Traversers and Pattern Matchers Ian Robinson http://ianSrobinson.com @ianSrobinson ianSrobinson@gmail.com
Traversers
Nodes and relationships
What does Ian like?
What vouchers is Ian entitled to? Including this one?
Yes
What vouchers is Jim entitled to? Including this one?
No
VouchersOfInterestQuery public class VouchersOfInterestQuery implements Query<Voucher> {     public List<Voucher> execute(final Customer customer, Object... params) {     	Collection<Node> nodes = customer.getNode()     		.traverse( Order.DEPTH_FIRST,  StopEvaluator.END_OF_GRAPH,          		new IsVoucherFor(customer),  Relationships.PROVIDES, Direction.INCOMING,  Relationships.LIKES, Direction.OUTGOING,  Relationships.APPLIES_TO, Direction.INCOMING)         .getAllNodes();         return toArray(nodes);     }     private class IsVoucherFor implements ReturnableEvaluator {     	...     }     private class IsSameCustomer implements ReturnableEvaluator {     	...     }     private List<Voucher> toArray(Collection<Node> nodes) { 	...     }   }
IsVoucherFor private class IsVoucherFor implements ReturnableEvaluator {   private final Customer customer;   public IsVoucherFor(Customer customer) { this.customer = customer;   }   @Override   public booleanisReturnableNode(TraversalPositiontp) {     if (!isVoucher(tp)) { return false; }     if (!isSponsored(tp)) { return true; }      Collection<Node> allNodes = tp.currentNode()       .traverse( Order.DEPTH_FIRST,  StopEvaluator.END_OF_GRAPH,          new IsSameCustomer(customer),  Relationships.SPONSORS, Direction.INCOMING,  Relationships.CUSTOMER_OF, Direction.INCOMING)       .getAllNodes();     return allNodes != null && allNodes.size() > 0;   }   ... }
isVoucher private class IsVoucherFor implements ReturnableEvaluator {   private final Customer customer;   public IsVoucherFor(Customer customer) { this.customer = customer;   }   @Override   public booleanisReturnableNode(TraversalPositiontp) {     if (!isVoucher(tp)) { return false; }     if (!isSponsored(tp)) { return true; }      Collection<Node> allNodes = tp.currentNode()       .traverse( Order.DEPTH_FIRST,  StopEvaluator.END_OF_GRAPH,          new IsSameCustomer(customer),  Relationships.SPONSORS, Direction.INCOMING,  Relationships.CUSTOMER_OF, Direction.INCOMING)       .getAllNodes();     return allNodes != null && allNodes.size() > 0;   }   ... } private booleanisVoucher(TraversalPositiontp) {     return tp.notStartNode()        && tp.lastRelationshipTraversed().isType(Relationships.APPLIES_TO);   }
isSponsored private class IsVoucherFor implements ReturnableEvaluator {   private final Customer customer;   public IsVoucherFor(Customer customer) { this.customer = customer;   }   @Override   public booleanisReturnableNode(TraversalPositiontp) {     if (!isVoucher(tp)) { return false; }     if (!isSponsored(tp)) { return true; }      Collection<Node> allNodes = tp.currentNode()       .traverse( Order.DEPTH_FIRST,  StopEvaluator.END_OF_GRAPH,          new IsSameCustomer(customer),  Relationships.SPONSORS, Direction.INCOMING,  Relationships.CUSTOMER_OF, Direction.INCOMING)       .getAllNodes();     return allNodes != null && allNodes.size() > 0;   }   ... } private booleanisSponsored(TraversalPositiontp) {     return tp.currentNode().hasRelationship( Relationships.SPONSORS, Direction.INCOMING); }
IsSameCustomer private class IsVoucherFor implements ReturnableEvaluator {   private final Customer customer;   public IsVoucherFor(Customer customer) { this.customer = customer;   }   @Override   public booleanisReturnableNode(TraversalPositiontp) {     if (!isVoucher(tp)) { return false; } if(!isSponsored(tp)) { return true; }      Collection<Node> allNodes = tp.currentNode()       .traverse( Order.DEPTH_FIRST,  StopEvaluator.END_OF_GRAPH,          new IsSameCustomer(customer),  Relationships.SPONSORS, Direction.INCOMING,  Relationships.CUSTOMER_OF, Direction.INCOMING)       .getAllNodes();     return allNodes != null && allNodes.size() > 0;   }   ... } private class IsSameCustomer implements ReturnableEvaluator {   private final Customer customer;   public IsSameCustomer(Customer customer) { this.customer = customer;   }   @Override   public booleanisReturnableNode(TraversalPositiontp) {     return tp.currentNode().getId() == customer.getNode().getId();   }  	 }
Pattern Matchers
Financial products
Purchases
Recommendations Customers who bought P also bought {Pa, …, Pb} Customers who bought {Pa, …, Pb} also bought {Px, …, Py} Etc Popularity is a function of number of purchasers and distance from original product (products close to the original product are ranked higher than those further away)
.2 Customers who bought an ISA also bought…
.2 Customers who bought Virgin Card and Fixed Rate Mortgage also bought…
Using pattern matchers public Collection<Recommendation> recommend(ProductcurrentProduct,  intdepthOfSearch) { HashMap<Long, Recommendation> recommendations =      new HashMap<Long, Recommendation>();   Node currentProductNode = currentProduct.getNode(); for(int depth = 1; depth <= depthOfSearch; depth++) { addNodePopularities(recommendations, currentProductNode, depth);   }   return recommendations.values(); } private void addNodePopularities(HashMap<Long, Recommendation> recommendations,    ... }
Building subgraph to match private void addNodePopularities(HashMap<Long, Recommendation> recommendations,    Node currentProductNode, int depth) { PatternNodefirstProduct = new PatternNode(); PatternNodelastProduct = firstProduct; for(inti = 1; i <= depth; i++) { PatternNodenextProduct = new PatternNode(); PatternNode customer = new PatternNode(); customer.createRelationshipTo(lastProduct,  DynamicRelationshipType.withName("Purchased") ); customer.createRelationshipTo(nextProduct,  DynamicRelationshipType.withName("Purchased") ); lastProduct = nextProduct;   } Iterable<PatternMatch> matches = PatternMatcher.getMatcher().match( firstProduct, currentProductNode);   for ( PatternMatch match : matches ) {     Node endNode = match.getNodeFor(lastProduct); incrementPopularity(recommendations, currentProductNode, endNode, depth);   } } C C P Plast Pfirst

More Related Content

What's hot

Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)Krzysztof Menżyk
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в MagentoMagecom Ukraine
 
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018 Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018 Codemotion
 
4. Метапрограмиране
4. Метапрограмиране4. Метапрограмиране
4. МетапрограмиранеStefan Kanev
 
Business Rules with Brick
Business Rules with BrickBusiness Rules with Brick
Business Rules with Brickbrian d foy
 
PyCon Siberia 2016. Не доверяйте тестам!
PyCon Siberia 2016. Не доверяйте тестам!PyCon Siberia 2016. Не доверяйте тестам!
PyCon Siberia 2016. Не доверяйте тестам!Ivan Tsyganov
 
Dutch php a short tale about state machine
Dutch php   a short tale about state machineDutch php   a short tale about state machine
Dutch php a short tale about state machineŁukasz Chruściel
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
 
FormsKit: reactive forms driven by state. UA Mobile 2017.
FormsKit: reactive forms driven by state. UA Mobile 2017.FormsKit: reactive forms driven by state. UA Mobile 2017.
FormsKit: reactive forms driven by state. UA Mobile 2017.UA Mobile
 
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
4Developers 2015: Be pragmatic, be SOLID - Krzysztof MenżykPROIDEA
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Taming forms with React
Taming forms with ReactTaming forms with React
Taming forms with ReactGreeceJS
 
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_FormZend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_FormJeremy Kendall
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsSam Hennessy
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable codeGeshan Manandhar
 
Java script introducation & basics
Java script introducation & basicsJava script introducation & basics
Java script introducation & basicsH K
 

What's hot (20)

Taming Command Bus
Taming Command BusTaming Command Bus
Taming Command Bus
 
The new form framework
The new form frameworkThe new form framework
The new form framework
 
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
 
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018 Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018
Lenses and Prisms in Swift - Elviro Rocca - Codemotion Rome 2018
 
Be pragmatic, be SOLID
Be pragmatic, be SOLIDBe pragmatic, be SOLID
Be pragmatic, be SOLID
 
4. Метапрограмиране
4. Метапрограмиране4. Метапрограмиране
4. Метапрограмиране
 
Business Rules with Brick
Business Rules with BrickBusiness Rules with Brick
Business Rules with Brick
 
PyCon Siberia 2016. Не доверяйте тестам!
PyCon Siberia 2016. Не доверяйте тестам!PyCon Siberia 2016. Не доверяйте тестам!
PyCon Siberia 2016. Не доверяйте тестам!
 
Dutch php a short tale about state machine
Dutch php   a short tale about state machineDutch php   a short tale about state machine
Dutch php a short tale about state machine
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
FormsKit: reactive forms driven by state. UA Mobile 2017.
FormsKit: reactive forms driven by state. UA Mobile 2017.FormsKit: reactive forms driven by state. UA Mobile 2017.
FormsKit: reactive forms driven by state. UA Mobile 2017.
 
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Taming forms with React
Taming forms with ReactTaming forms with React
Taming forms with React
 
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_FormZend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable code
 
Java script introducation & basics
Java script introducation & basicsJava script introducation & basics
Java script introducation & basics
 

Viewers also liked

A seminar on neo4 j
A seminar on neo4 jA seminar on neo4 j
A seminar on neo4 jRishikese MR
 
5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard LawrenceSkills Matter
 
Discrete Mathematics & Its Applications (Graphs)
Discrete Mathematics & Its Applications (Graphs)Discrete Mathematics & Its Applications (Graphs)
Discrete Mathematics & Its Applications (Graphs)Fahrul Usman
 
Noli me tangere kabanata 25 26
Noli me tangere kabanata 25 26Noli me tangere kabanata 25 26
Noli me tangere kabanata 25 26mojarie madrilejo
 
Montreal Girl Geeks: Building the Modern Web
Montreal Girl Geeks: Building the Modern WebMontreal Girl Geeks: Building the Modern Web
Montreal Girl Geeks: Building the Modern WebRachel Andrew
 

Viewers also liked (7)

A seminar on neo4 j
A seminar on neo4 jA seminar on neo4 j
A seminar on neo4 j
 
5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence
 
Discrete Mathematics & Its Applications (Graphs)
Discrete Mathematics & Its Applications (Graphs)Discrete Mathematics & Its Applications (Graphs)
Discrete Mathematics & Its Applications (Graphs)
 
Noli me tangere kabanata 25 26
Noli me tangere kabanata 25 26Noli me tangere kabanata 25 26
Noli me tangere kabanata 25 26
 
Internet of Things
Internet of ThingsInternet of Things
Internet of Things
 
Montreal Girl Geeks: Building the Modern Web
Montreal Girl Geeks: Building the Modern WebMontreal Girl Geeks: Building the Modern Web
Montreal Girl Geeks: Building the Modern Web
 
Digital in 2017 Global Overview
Digital in 2017 Global OverviewDigital in 2017 Global Overview
Digital in 2017 Global Overview
 

Similar to Neo4 J

DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...Matthias Noback
 
Oop php 5
Oop php 5Oop php 5
Oop php 5phpubl
 
React Native - Workshop
React Native - WorkshopReact Native - Workshop
React Native - WorkshopFellipe Chagas
 
Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1Augustin Bralley
 
Beyond Design Principles and Patterns
Beyond Design Principles and PatternsBeyond Design Principles and Patterns
Beyond Design Principles and PatternsMatthias Noback
 
重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1Chris Huang
 
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...James Titcumb
 
CodingSerbia2014-JavaVSPig
CodingSerbia2014-JavaVSPigCodingSerbia2014-JavaVSPig
CodingSerbia2014-JavaVSPigDusan Zamurovic
 
Chapter 8- Advanced Views and URLconfs
Chapter 8- Advanced Views and URLconfsChapter 8- Advanced Views and URLconfs
Chapter 8- Advanced Views and URLconfsVincent Chien
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo Ali Parmaksiz
 
Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляSergey Platonov
 
Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Matthias Noback
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...Mateusz Zalewski
 
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze..."Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...Mateusz Zalewski
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)James Titcumb
 
Linq Sanjay Vyas
Linq   Sanjay VyasLinq   Sanjay Vyas
Linq Sanjay Vyasrsnarayanan
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgetsvelveeta_512
 
#pugMi - DDD - Value objects
#pugMi - DDD - Value objects#pugMi - DDD - Value objects
#pugMi - DDD - Value objectsSimone Gentili
 

Similar to Neo4 J (20)

DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
 
Oop php 5
Oop php 5Oop php 5
Oop php 5
 
React Native - Workshop
React Native - WorkshopReact Native - Workshop
React Native - Workshop
 
Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1
 
Beyond Design Principles and Patterns
Beyond Design Principles and PatternsBeyond Design Principles and Patterns
Beyond Design Principles and Patterns
 
重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1
 
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
 
CodingSerbia2014-JavaVSPig
CodingSerbia2014-JavaVSPigCodingSerbia2014-JavaVSPig
CodingSerbia2014-JavaVSPig
 
Chapter 8- Advanced Views and URLconfs
Chapter 8- Advanced Views and URLconfsChapter 8- Advanced Views and URLconfs
Chapter 8- Advanced Views and URLconfs
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
 
Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуля
 
Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
 
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze..."Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
"Kto to pisał?!... A, to ja.", czyli sposoby, żeby znienawidzić siebie z prze...
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Linq Sanjay Vyas
Linq   Sanjay VyasLinq   Sanjay Vyas
Linq Sanjay Vyas
 
Structure on a freeform world
Structure on a freeform worldStructure on a freeform world
Structure on a freeform world
 
Php & my sql
Php & my sqlPhp & my sql
Php & my sql
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
 
#pugMi - DDD - Value objects
#pugMi - DDD - Value objects#pugMi - DDD - Value objects
#pugMi - DDD - Value objects
 

More from Skills Matter

Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applicationsSkills Matter
 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmScala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmSkills Matter
 
Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimSkills Matter
 
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Skills Matter
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlSkills Matter
 
Cukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsCukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsSkills Matter
 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Skills Matter
 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Skills Matter
 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldProgressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldSkills Matter
 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Skills Matter
 
Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Skills Matter
 
A poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingA poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingSkills Matter
 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveSkills Matter
 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSkills Matter
 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tSkills Matter
 

More from Skills Matter (20)

Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmScala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
 
Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheim
 
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberl
 
Cukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsCukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.js
 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldProgressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source world
 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
 
Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#
 
A poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingA poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testing
 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-dive
 
Serendipity-neo4j
Serendipity-neo4jSerendipity-neo4j
Serendipity-neo4j
 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelism
 
Plug 20110217
Plug   20110217Plug   20110217
Plug 20110217
 
Lug presentation
Lug presentationLug presentation
Lug presentation
 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_t
 
Plug saiku
Plug   saikuPlug   saiku
Plug saiku
 
Huguk lily
Huguk lilyHuguk lily
Huguk lily
 

Recently uploaded

Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 

Recently uploaded (20)

Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 

Neo4 J

  • 1. Neo4J Traversers and Pattern Matchers Ian Robinson http://ianSrobinson.com @ianSrobinson ianSrobinson@gmail.com
  • 5. What vouchers is Ian entitled to? Including this one?
  • 6. Yes
  • 7. What vouchers is Jim entitled to? Including this one?
  • 8. No
  • 9. VouchersOfInterestQuery public class VouchersOfInterestQuery implements Query<Voucher> { public List<Voucher> execute(final Customer customer, Object... params) { Collection<Node> nodes = customer.getNode() .traverse( Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH, new IsVoucherFor(customer), Relationships.PROVIDES, Direction.INCOMING, Relationships.LIKES, Direction.OUTGOING, Relationships.APPLIES_TO, Direction.INCOMING) .getAllNodes(); return toArray(nodes); } private class IsVoucherFor implements ReturnableEvaluator { ... } private class IsSameCustomer implements ReturnableEvaluator { ... } private List<Voucher> toArray(Collection<Node> nodes) { ... } }
  • 10. IsVoucherFor private class IsVoucherFor implements ReturnableEvaluator { private final Customer customer; public IsVoucherFor(Customer customer) { this.customer = customer; } @Override public booleanisReturnableNode(TraversalPositiontp) { if (!isVoucher(tp)) { return false; } if (!isSponsored(tp)) { return true; } Collection<Node> allNodes = tp.currentNode() .traverse( Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH, new IsSameCustomer(customer), Relationships.SPONSORS, Direction.INCOMING, Relationships.CUSTOMER_OF, Direction.INCOMING) .getAllNodes(); return allNodes != null && allNodes.size() > 0; } ... }
  • 11. isVoucher private class IsVoucherFor implements ReturnableEvaluator { private final Customer customer; public IsVoucherFor(Customer customer) { this.customer = customer; } @Override public booleanisReturnableNode(TraversalPositiontp) { if (!isVoucher(tp)) { return false; } if (!isSponsored(tp)) { return true; } Collection<Node> allNodes = tp.currentNode() .traverse( Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH, new IsSameCustomer(customer), Relationships.SPONSORS, Direction.INCOMING, Relationships.CUSTOMER_OF, Direction.INCOMING) .getAllNodes(); return allNodes != null && allNodes.size() > 0; } ... } private booleanisVoucher(TraversalPositiontp) { return tp.notStartNode() && tp.lastRelationshipTraversed().isType(Relationships.APPLIES_TO); }
  • 12. isSponsored private class IsVoucherFor implements ReturnableEvaluator { private final Customer customer; public IsVoucherFor(Customer customer) { this.customer = customer; } @Override public booleanisReturnableNode(TraversalPositiontp) { if (!isVoucher(tp)) { return false; } if (!isSponsored(tp)) { return true; } Collection<Node> allNodes = tp.currentNode() .traverse( Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH, new IsSameCustomer(customer), Relationships.SPONSORS, Direction.INCOMING, Relationships.CUSTOMER_OF, Direction.INCOMING) .getAllNodes(); return allNodes != null && allNodes.size() > 0; } ... } private booleanisSponsored(TraversalPositiontp) { return tp.currentNode().hasRelationship( Relationships.SPONSORS, Direction.INCOMING); }
  • 13. IsSameCustomer private class IsVoucherFor implements ReturnableEvaluator { private final Customer customer; public IsVoucherFor(Customer customer) { this.customer = customer; } @Override public booleanisReturnableNode(TraversalPositiontp) { if (!isVoucher(tp)) { return false; } if(!isSponsored(tp)) { return true; } Collection<Node> allNodes = tp.currentNode() .traverse( Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH, new IsSameCustomer(customer), Relationships.SPONSORS, Direction.INCOMING, Relationships.CUSTOMER_OF, Direction.INCOMING) .getAllNodes(); return allNodes != null && allNodes.size() > 0; } ... } private class IsSameCustomer implements ReturnableEvaluator { private final Customer customer; public IsSameCustomer(Customer customer) { this.customer = customer; } @Override public booleanisReturnableNode(TraversalPositiontp) { return tp.currentNode().getId() == customer.getNode().getId(); } }
  • 17. Recommendations Customers who bought P also bought {Pa, …, Pb} Customers who bought {Pa, …, Pb} also bought {Px, …, Py} Etc Popularity is a function of number of purchasers and distance from original product (products close to the original product are ranked higher than those further away)
  • 18. .2 Customers who bought an ISA also bought…
  • 19. .2 Customers who bought Virgin Card and Fixed Rate Mortgage also bought…
  • 20. Using pattern matchers public Collection<Recommendation> recommend(ProductcurrentProduct, intdepthOfSearch) { HashMap<Long, Recommendation> recommendations = new HashMap<Long, Recommendation>(); Node currentProductNode = currentProduct.getNode(); for(int depth = 1; depth <= depthOfSearch; depth++) { addNodePopularities(recommendations, currentProductNode, depth); } return recommendations.values(); } private void addNodePopularities(HashMap<Long, Recommendation> recommendations, ... }
  • 21. Building subgraph to match private void addNodePopularities(HashMap<Long, Recommendation> recommendations, Node currentProductNode, int depth) { PatternNodefirstProduct = new PatternNode(); PatternNodelastProduct = firstProduct; for(inti = 1; i <= depth; i++) { PatternNodenextProduct = new PatternNode(); PatternNode customer = new PatternNode(); customer.createRelationshipTo(lastProduct, DynamicRelationshipType.withName("Purchased") ); customer.createRelationshipTo(nextProduct, DynamicRelationshipType.withName("Purchased") ); lastProduct = nextProduct; } Iterable<PatternMatch> matches = PatternMatcher.getMatcher().match( firstProduct, currentProductNode); for ( PatternMatch match : matches ) { Node endNode = match.getNodeFor(lastProduct); incrementPopularity(recommendations, currentProductNode, endNode, depth); } } C C P Plast Pfirst