O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

How Shutl Delivers Even Faster Using Neo4J

565 visualizações

Publicada em

Video and slides synchronized, mp3 and slide download available at URL http://bit.ly/1uRYaAR.

Volker Pacher, Sam Phillips present key differences between relational databases and graph databases, and how they use the later to model a complex domain and to gain insights into their data. Filmed at qconlondon.com.

Sam Phillips is Head of Engineering for eBay's Local Delivery team, bringing super fast delivery to customers in the UK and US. Volker Pacher is a Senior Developer at eBay Local Delivery. Before its acquisition by eBay, he was a member of the core team at Shutl helping to transition from a monolithic application to SOA and introducing new technologies, among them Neo4j.

Publicada em: Tecnologia
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

How Shutl Delivers Even Faster Using Neo4J

  1. 1. Watch the video with slide synchronization on InfoQ.com! http://www.infoq.com/presentations /shutl-neo4j-graph-db InfoQ.com: News & Community Site • 750,000 unique visitors/month • Published in 4 languages (English, Chinese, Japanese and Brazilian Portuguese) • Post content from our QCon conferences • News 15-20 / week • Articles 3-4 / week • Presentations (videos) 12-15 / week • Interviews 2-3 / week • Books 1 / month
  2. 2. Presented at QCon London www.qconlondon.com Purpose of QCon - to empower software development by facilitating the spread of knowledge and innovation Strategy - practitioner-driven conference designed for YOU: influencers of change and innovation in your teams - speakers and topics driving the evolution and innovation - connecting and catalyzing the influencers and innovators Highlights - attended by more than 12,000 delegates since 2007 - held in 9 cities worldwide
  3. 3. How Shutl Delivers Even Faster Using Neo4j Sam Phillips and Volker Pacher @samsworldofno @vpacher
  4. 4. Sam Phillips Volker Pacher
  5. 5. Graphs at Shutl
  6. 6. Graphs at Shutl • Graph databases are awesome
  7. 7. Graphs at Shutl • Graph databases are awesome • We’ve seen lots of the talks about modelling
  8. 8. Graphs at Shutl • Graph databases are awesome • We’ve seen lots of the talks about modelling • But querying is important too
  9. 9. Graphs at Shutl • Graph databases are awesome • We’ve seen lots of the talks about modelling • But querying is important too • So let’s talk about querying too!
  10. 10. Show of hands
  11. 11. Show of hands • Who has used graph databases before?
  12. 12. Show of hands • Who has used graph databases before? • Who has used Neo4j before?
  13. 13. Shutl
  14. 14. Shutl
  15. 15. ECOMMERCE IS QUICK & CONVENIENT
  16. 16. ECOMMERCE IS QUICK & CONVENIENT
  17. 17. PAYPAL FOR AWESOME DELIVERY
  18. 18. PAYPAL FOR AWESOME DELIVERY
  19. 19. PAYPAL FOR AWESOME DELIVERY Branded, super quick delivery that people trust, embedded in merchant websites
  20. 20. HUB & SPOKE A B
  21. 21. HUB & SPOKE A B
  22. 22. HUB & SPOKE A B Only cost effective means to deliver 10+ miles but slow and unpredictable
  23. 23. HUB & SPOKE Only cost effective means to deliver 10+ miles but slow and unpredictable A B
  24. 24. HUB & SPOKE Only cost effective means to deliver 10+ miles but slow and unpredictable A B POINT TO POINT A B
  25. 25. HUB & SPOKE Only cost effective means to deliver 10+ miles but slow and unpredictable A B POINT TO POINT A B Fast and predictable but cost prohibitive over longer distances
  26. 26. HUB & SPOKE 97% Courier, Express & Parcel Market
  27. 27. POINT TO POINT 3% Courier, Express & Parcel Market
  28. 28. POINT TO POINT +7,500 more! 3% Courier, Express & Parcel Market
  29. 29. POINT TO POINT
  30. 30. SHOP
  31. 31. Shutl generates a quote from each relevant carrier within platform SHOP $$ $$$ $ $$ $ $
  32. 32. Shutl generates a quote from each relevant carrier within platform Optimum picked based on price & quality rating SHOP $$ $$$ $ $$ $ $$
  33. 33. SHOP SHOP
  34. 34. On checkout, delivery sent via API into chosen carrier’s transportation system SHOP $$ SHOP
  35. 35. On checkout, delivery sent via API into chosen carrier’s transportation system Courier collects from nearest store and delivers to shopper SHOP $$
  36. 36. Delivery status updated in real-time, performance compared against SLA & carrier quality rating updated Better performing carriers get more deliveries & can demand higher prices
  37. 37. Delivery status updated in real-time, performance compared against SLA & carrier quality rating updated Better performing carriers get more deliveries & can demand higher prices
  38. 38. Delivery status updated in real-time, performance compared against SLA & carrier quality rating updated Better performing carriers get more deliveries & can demand higher prices
  39. 39. Track your order online…
  40. 40. FEEDBACK Quality paramount since we are motivated by LTV of shopper
  41. 41. FEEDBACK Quality paramount since we are motivated by LTV of shopper
  42. 42. FEEDBACK Shutl sends feedback email to consumer seconds after they have received delivery asking to rate qualitative aspects of experience
  43. 43. FEEDBACK Feedback streamed unedited to shutl.com/feedback & facebook
  44. 44. FEEDBACK
  45. 45. FEEDBACK
  46. 46. FEEDBACK
  47. 47. FEEDBACK
  48. 48. SHUTL IS NOW AN COMPANY
  49. 49. Version One Ruby 1.8, Rails 2.3 and MySQL
  50. 50. Version One Ruby 1.8, Rails 2.3 and MySQL
  51. 51. Version One Ruby 1.8, Rails 2.3 and MySQL • Well-known tale: built quickly, worked slowly, tough to maintain • Getting a quote for an hour time-slot took over 4 seconds
  52. 52. Here is the Shutl price calendar
  53. 53. Here is the Shutl price calendar To generate this in V1, the merchant site would have had to call Shutl to get available slots (2 seconds)
  54. 54. Here is the Shutl price calendar To generate this in V1, the merchant site would have had to call Shutl to get available slots (2 seconds) Then, they would have to call Shutl to generate a quote for each slot - for two days of store opening, that’s 20+ slots
  55. 55. Here is the Shutl price calendar To generate this in V1, the merchant site would have had to call Shutl to get available slots (2 seconds) Then, they would have to call Shutl to generate a quote for each slot - for two days of store opening, that’s 20+ slots So, that’s 2 + (20 x 4) seconds, 1:22 to generate the data for this calendar
  56. 56. Here is the Shutl price calendar To generate this in V1, the merchant site would have had to call Shutl to get available slots (2 seconds) Then, they would have to call Shutl to generate a quote for each slot - for two days of store opening, that’s 20+ slots So, that’s 2 + (20 x 4) seconds, 1:22 to generate the data for this calendar In V1, this UX could never have happened.
  57. 57. V2
  58. 58. • Broke app into services V2 • Services focused around functions like quoting, booking, and giving feedback • Key goal for the project was improving the speed of the quoting operation, which is where we used graph databases
  59. 59. V1 V2
  60. 60. V1 V2 • Quoting for 20 windows down from 82000 ms to 800 ms
  61. 61. V1 V2 • Quoting for 20 windows down from 82000 ms to 800 ms • Code complexity much reduced
  62. 62. V1 V2 • Quoting for 20 windows down from 82000 ms to 800 ms • Code complexity much reduced
  63. 63. A large part of the success of our rewrite was down to the graph database.
  64. 64. What is a graph anyway?
  65. 65. a simple graph a collection of vertices (nodes) connected by edges (relationships)
  66. 66. a short history the seven bridges of Königsberg (1735)! Leonard Euler
  67. 67. the seven bridges of Königsberg (1735)!
  68. 68. the seven bridges of Königsberg (1735)!
  69. 69. the seven bridges of Königsberg (1735)!
  70. 70. the seven bridges of Königsberg (1735)!
  71. 71. the seven bridges of Königsberg (1735)!
  72. 72. Euler walk each node has an even degree
  73. 73. Euler walk
  74. 74. Euler walk
  75. 75. Euler walk two nodes have an odd degree
  76. 76. Euler walk two nodes have an odd degree
  77. 77. Euler walk no two nodes have an odd degree
  78. 78. directed graph each relationship has a direction or one start node and one end node
  79. 79. property graph nodes contain properties (key, value) relationships have a type and are always directed relationships can contain properties too Person name: Sam Person name: Volker :friends :knows since: 2005 Person name: Megan :friends Company name: eBay :works_for :works_for
  80. 80. The Case for Graph Databases
  81. 81. relationships are explicit stored
  82. 82. additive domain modelling
  83. 83. whiteboard friendly
  84. 84. traversals of relationships are easy and very fast
  85. 85. DB performance remains relatively constant as queries are localised to its portion of the graph. O(1) for same query
  86. 86. a graph is its own index (constant query performance)
  87. 87. a graph is its own index (constant query performance)
  88. 88. a graph is its own index (constant query performance)
  89. 89. the case for Neo4j
  90. 90. standalone or embedded in jvm
  91. 91. ruby/jruby
  92. 92. ruby libraries - neo4j gem by Andreas Ronge (https://github.com/andreasronge/neo4j)
  93. 93. cypher
  94. 94. the neotech guys are awesome
  95. 95. Querying the graph: Cypher declarative query language specific to neo4j easy to learn and intuitive use specific patterns to query for (something that looks like ‘this’) inspired partly by SQL (WHERE and ORDER BY) and SPARQL (pattern matching) focuses on what to query for and not how to query for it switch from a mySQl world is made easier by the use of cypher instead of having to learn a traversal framework straight away
  96. 96. cypher clauses START: Starting points in the graph, obtained via index lookups or by element IDs. MATCH: The graph pattern to match, bound to the starting points in START. WHERE: Filtering criteria. RETURN: What to return. CREATE: Creates nodes and relationships. DELETE: Removes nodes, relationships and properties. SET: Set values to properties. FOREACH: Performs updating actions once per element in a list. WITH: Divides a query into multiple, distinct parts
  97. 97. cypher clauses START: Starting points in the graph, obtained via index lookups or by element IDs. MATCH: The graph pattern to match, bound to the starting points in START. WHERE: Filtering criteria. RETURN: What to return. CREATE: Creates nodes and relationships. DELETE: Removes nodes, relationships and properties. SET: Set values to properties. FOREACH: Performs updating actions once per element in a list. WITH: Divides a query into multiple, distinct parts
  98. 98. an example Person name: Sam Person name: Volker :friends :knows since: 2005 Person name: Megan :friends Company name: eBay :works_for :works_for Person name: Jim :friends :works_for Company name: neotech
  99. 99. find all the companies my friends work for MATCH (person{ name:’Volker’ }) -[:friends] - (person) - [:works_for]-> company RETURN company
  100. 100. find all the companies my friends work for MATCH (person{ name:’Volker’ }) -[:friends] - (person) - [:works_for]-> company RETURN company
  101. 101. find all the companies my friends work for MATCH (person{ name:’Volker’ }) -[:friends] - (person) - [:works_for]-> company RETURN company Person name: Sam Person name: Volker :friends :knows since: 2005 Person name: Megan :friends Company name: eBay :works_for :works_for Person name: Jim :friends :works_for Company name: neotech
  102. 102. find all the companies my friend’s friends work for MATCH (person{ name:’Volker’ }) - [:friends*2..2]-(person) - [:works_for] -> company RETURN company
  103. 103. find all the companies my friend’s friends work for MATCH (person{ name:’Volker’ }) - [:friends*2..2]-(person) - [:works_for] -> company RETURN company
  104. 104. find all the companies my friend’s friends work for MATCH (person{ name:’Volker’ }) - [:friends*2..2]-(person) - [:works_for] -> company RETURN company Person name: Sam Person name: Volker :friends :knows since: 2005 Person name: Megan :friends Company name: eBay :works_for :works_for Person name: Jim :friends :works_for Company name: neotech
  105. 105. find all my friends who work for neotech MATCH (person{ name:’Volker’ }) -[:friends] -(friends) - [:works_for]-> company WHERE company.name = ‘neotech’ RETURN friends
  106. 106. find all my friends who work for neotech MATCH (person{ name:’Volker’ }) -[:friends] -(friends) - [:works_for]-> company WHERE company.name = ‘neotech’ RETURN friends
  107. 107. find all my friends who work for neotech MATCH (person{ name:’Volker’ }) -[:friends] -(friends) - [:works_for]-> company WHERE company.name = ‘neotech’ RETURN friends Person name: Sam Person name: Volker :friends :knows since: 2005 Person name: Megan :friends Company name: eBay :works_for :works_for Person name: Jim :friends :works_for Company name: neotech
  108. 108. a good place to try it out: ! http://console.neo4j.org/ ! http://gist.neo4j.org/
  109. 109. coverage example Locality id = california Locality id = marin_county Locality id = 94901 :contains :contains Locality id = 94903 :contains :contains Locality id = 94902
  110. 110. coverage example Locality id = california Locality id = marin_county Locality id = 94901 :contains :contains Locality id = 94903 :contains :contains Locality id = 94902 :operates :operates Carrier id = carrier_1
  111. 111. coverage example Locality id = california Locality id = marin_county Locality id = 94901 :contains Store id = ebay_store :located :contains Locality id = 94903 :contains :contains Locality id = 94902 :operates :operates Carrier id = carrier_1
  112. 112. coverage example Locality id = california Locality id = marin_county Locality id = 94901 :contains Store id = ebay_store :located :contains Locality id = 94903 :contains :contains Locality id = 94902 :operates Carrier id = carrier_2 :operates :operates Carrier id = carrier_1
  113. 113. MATCH (store{ id:’ebay_store’ }) -[:located] -> (locality) <- [:operates]- carrier RETURN carrier the query
  114. 114. the query MATCH (store{ id:’ebay_store’ }) -[:located] -> (locality) <- [:operates]- carrier RETURN carrier
  115. 115. MATCH (store{ id:’ebay_store’ }) -[:located] -> (locality) <- [:operates]- carrier RETURN carrier the query Locality id = california Locality id = 94902 Locality id = marin_county Locality id = 94901 :contains Store id = ebay_store :located :contains Locality id = 94903 :contains :contains :operates :operates Carrier id = carrier_1
  116. 116. MATCH (store{ id:’ebay_store’ }) -[:located] -> () <- [:contains*0..2] - (locality) <- [:operates]- carrier RETURN carrier the query
  117. 117. MATCH (store{ id:’ebay_store’ }) -[:located] -> () <- [:contains*0..2] - (locality) <- [:operates]- carrier RETURN carrier the query
  118. 118. MATCH (store{ id:’ebay_store’ }) -[:located] -> () <- [:contains*0..2] - (locality) <- [:operates]- carrier RETURN carrier the query Locality id = california Locality id = marin_county Locality id = 94901 :contains Store id = ebay_store :located :contains Locality id = 94903 :contains :contains Locality id = 94902 :operates Carrier id = carrier_2 :operates :operates Carrier id = carrier_1
  119. 119. MATCH (store{ id:’ebay_store’ }) -[:located] -> () <- [:contains*0..2] - (locality) <- [:operates]- carrier RETURN carrier the query Locality id = california Locality id = marin_county Locality id = 94901 :contains Store id = ebay_store :located :contains Locality id = 94903 :contains :contains Locality id = 94902 :operates Carrier id = carrier_2 :operates :operates Carrier id = carrier_1
  120. 120. MATCH (store{ id:’ebay_store’ }) -[:located] -> () <- [:contains*0..2] - (locality) <- [:operates]- carrier RETURN carrier the query Locality id = california Locality id = marin_county Locality id = 94901 :contains Store id = ebay_store :located :contains Locality id = 94903 :contains :contains Locality id = 94902 :operates Carrier id = carrier_2 :operates :operates Carrier id = carrier_1
  121. 121. MATCH (store{ id:’ebay_store’ }) -[:located] -> () <- [:contains*0..2] - (locality) <- [:operates]- carrier RETURN carrier the query Locality id = california Locality id = marin_county Locality id = 94901 :contains Store id = ebay_store :located :contains Locality id = 94903 :contains :contains Locality id = 94902 :operates Carrier id = carrier_2 :operates :operates Carrier id = carrier_1
  122. 122. SELECT * FROM carriers LEFT JOIN locations ON carrier.location_id = location.id LEFT JOIN stores ON stores.location_id = carrier.location_id WHERE stores.name = ‘ebay_store’
  123. 123. SELECT * FROM carriers LEFT JOIN locations ON carrier.location_id = location.id OR carrier.location_id = location.parent_id LEFT JOIN stores ON stores.location_id = carrier.location_id WHERE stores.name = ‘ebay_store’
  124. 124. ?
  125. 125. MATCH (store{ id:’ebay_store’ }) -[:located] -> () <- [:contains*0..2] - (locality) <- [:operates]- carrier RETURN carrier
  126. 126. representing dates/times root (0) :year_2014 Year: 2013 :year_2015 Year: 2015 :month_06 :month_05 :month_01 Month: 05 Month: 01 Month: 06 :day_24 :day_25 Day: 24 Day: 25 :day_26 Day: 26 :happens :happens :happens :happens Event 1 Event 2 Event 3
  127. 127. find all events on a specific day START root=node(0) MATCH root - [:year_2014] -> () -[:month_05] -> ()- [:day_24] -> () - [:happens] -> event RETURN event
  128. 128. find all events on a specific day START root=node(0) MATCH root - [:year_2014] -> () -[:month_05] -> ()- [:day_24] -> () - [:happens] -> event RETURN event
  129. 129. find all events on a specific day START root=node(0) MATCH root - [:year_2014] -> () -[:month_05] -> ()- [:day_24] -> () - [:happens] -> event RETURN event root (0) :year_2014 Year: 2013 :year_2015 Year: 2015 :month_06 :month_05 :month_01 Month: 05 Month: 01 Month: 06 :day_24 :day_25 Day: 24 Day: 25 :day_26 Day: 26 :happens :happens :happens :happens Event 1 Event 2 Event 3
  130. 130. find all events on a specific day START root=node(0) MATCH root - [:year_2014] -> () -[:month_05] -> ()- [:day_24] -> () - [:happens] -> event RETURN event root (0) :year_2014 Year: 2013 :year_2015 Year: 2015 :month_06 :month_05 :month_01 Month: 05 Month: 01 Month: 06 :day_24 :day_25 Day: 24 Day: 25 :day_26 Day: 26 :happens :happens :happens :happens Event 1 Event 2 Event 3
  131. 131. find all events on a specific day START root=node(0) MATCH root - [:year_2014] -> () -[:month_05] -> ()- [:day_24] -> () - [:happens] -> event RETURN event root (0) :year_2014 Year: 2013 :year_2015 Year: 2015 :month_06 :month_05 :month_01 Month: 05 Month: 01 Month: 06 :day_24 :day_25 Day: 24 Day: 25 :day_26 Day: 26 :happens :happens :happens :happens Event 1 Event 2 Event 3
  132. 132. find all events on a specific day START root=node(0) MATCH root - [:year_2014] -> () -[:month_05] -> ()- [:day_24] -> () - [:happens] -> event RETURN event root (0) :year_2014 Year: 2013 :year_2015 Year: 2015 :month_06 :month_05 :month_01 Month: 05 Month: 01 Month: 06 :day_24 :day_25 Day: 24 Day: 25 :day_26 Day: 26 :happens :happens :happens :happens Event 1 Event 2 Event 3
  133. 133. find all events on a specific day START root=node(0) MATCH root - [:year_2014] -> () -[:month_05] -> ()- [:day_24] -> () - [:happens] -> event RETURN event root (0) :year_2014 Year: 2013 :year_2015 Year: 2015 :month_06 :month_05 :month_01 Month: 05 Month: 01 Month: 06 :day_24 :day_25 Day: 24 Day: 25 :day_26 Day: 26 :happens :happens :happens :happens Event 1 Event 2 Event 3
  134. 134. find all events on a specific day START root=node(0) MATCH root - [:year_2014] -> () -[:month_05] -> ()- [:day_24] -> () - [:happens] -> event RETURN event root (0) :year_2014 Year: 2013 :year_2015 Year: 2015 :month_06 :month_05 :month_01 Month: 05 Month: 01 Month: 06 :day_24 :day_25 Day: 24 Day: 25 :day_26 Day: 26 :happens :happens :happens :happens Event 1 Event 2 Event 3
  135. 135. all together Locality id = california Locality id = marin_county :contains Locality id = 94901 :contains Store id = ebay_store :located :available {premium: 1.5} Carrier id = carrier_1 :operates root (0) :year_2014 Year: 2013 :month_05 Month: 05 :day_24 Day: 24 hour 09 :hour_09 hour 10 :hour_10 hour 11 :hour_11 :available {premium: 1}
  136. 136. all together MATCH (store{ id:’ebay_store’ }) -[:located] -> (locality) <- [:operates]- carrier - [available:available] -> () <- [:hour_10] - () <- [:day_24] - () [:month_05] - () [:year_2014] - () RETURN carrier, available.premium as premium
  137. 137. all together MATCH (store{ id:’ebay_store’ }) -[:located] -> (locality) <- [:operates]- carrier - [available:available] -> () <- [:hour_10] - () <- [:day_24] - () [:month_05] - () [:year_2014] - () RETURN carrier, available.premium as premium
  138. 138. all together MATCH (store{ id:’ebay_store’ }) -[:located] -> (locality) <- [:operates]- carrier - [available:available] -> () <- [:hour_10] - () <- [:day_24] - () [:month_05] - () [:year_2014] - () RETURN carrier, available.premium as premium Locality id = california Locality id = marin_county :contains Locality id = 94901 :contains Store id = ebay_store :located :available {premium: 1.5} Carrier id = carrier_1 :operates root (0) :year_2014 Year: 2013 :month_05 Month: 05 :day_24 Day: 24 hour 09 :hour_09 hour 10 :hour_10 hour 11 :hour_11 :available {premium: 1}
  139. 139. Other graph uses
  140. 140. Other graph uses • Recommendation engines
  141. 141. Other graph uses • Recommendation engines • Organisational analysis
  142. 142. Other graph uses • Recommendation engines • Organisational analysis • Graphing your infrastructure
  143. 143. Some gotchas
  144. 144. Some gotchas • There was a learning curve in switching from a relational mentality to a graph one
  145. 145. Some gotchas • There was a learning curve in switching from a relational mentality to a graph one • Tooling not as mature as in the relational world
  146. 146. Some gotchas • There was a learning curve in switching from a relational mentality to a graph one • Tooling not as mature as in the relational world • No out of the box solution for db migrations
  147. 147. Some gotchas • There was a learning curve in switching from a relational mentality to a graph one • Tooling not as mature as in the relational world • No out of the box solution for db migrations • Seeding an embedded database was unfamiliar
  148. 148. Testing was a challenge
  149. 149. Testing was a challenge • Setting up scenarios for tests was tedious
  150. 150. Testing was a challenge • Setting up scenarios for tests was tedious • Built our own tool based on the geoff syntax developed by Nigel Small
  151. 151. Testing was a challenge • Setting up scenarios for tests was tedious • Built our own tool based on the geoff syntax developed by Nigel Small • Geoff allows modelling of graphs in textual form and provides an interface to insert them into an existing graph
  152. 152. Testing was a challenge • Setting up scenarios for tests was tedious • Built our own tool based on the geoff syntax developed by Nigel Small • Geoff allows modelling of graphs in textual form and provides an interface to insert them into an existing graph (A) {“name”: “Alice”}
  153. 153. Testing was a challenge • Setting up scenarios for tests was tedious • Built our own tool based on the geoff syntax developed by Nigel Small • Geoff allows modelling of graphs in textual form and provides an interface to insert them into an existing graph (A) {“name”: “Alice”} (B) {“name”: “Bob”}
  154. 154. Testing was a challenge • Setting up scenarios for tests was tedious • Built our own tool based on the geoff syntax developed by Nigel Small • Geoff allows modelling of graphs in textual form and provides an interface to insert them into an existing graph (A) {“name”: “Alice”} (B) {“name”: “Bob”} (A) -[:KNOWS] -> (B)
  155. 155. Testing was a challenge • Setting up scenarios for tests was tedious • Built our own tool based on the geoff syntax developed by Nigel Small • Geoff allows modelling of graphs in textual form and provides an interface to insert them into an existing graph (A) {“name”: “Alice”} (B) {“name”: “Bob”} (A) -[:KNOWS] -> (B) • We created a Ruby dsl for modelling a graph and inserting it into the db that works with factory_girl
  156. 156. Testing was a challenge • Setting up scenarios for tests was tedious • Built our own tool based on the geoff syntax developed by Nigel Small • Geoff allows modelling of graphs in textual form and provides an interface to insert them into an existing graph (A) {“name”: “Alice”} (B) {“name”: “Bob”} (A) -[:KNOWS] -> (B) • We created a Ruby dsl for modelling a graph and inserting it into the db that works with factory_girl • Open source - https://github.com/shutl/geoff
  157. 157. Wrap Up
  158. 158. Wrap Up • Neo4j and graph theory enabled Shutl to achieve big performance increases in its most important operation - calculating delivery prices
  159. 159. Wrap Up • Neo4j and graph theory enabled Shutl to achieve big performance increases in its most important operation - calculating delivery prices • It’s a new tool based on tested theory, and cypher is the first language that allows you to query graphs in a declarative way (like SQL)
  160. 160. Wrap Up • Neo4j and graph theory enabled Shutl to achieve big performance increases in its most important operation - calculating delivery prices • It’s a new tool based on tested theory, and cypher is the first language that allows you to query graphs in a declarative way (like SQL) • Tooling and adoption is immature but getting better all the time
  161. 161. Thank you! ! Any questions? Sam Phillips Head of Engineering ! @samsworldofno http://samsworldofno.com sam@shutl.com Volker Pacher Senior Developer ! @vpacher https://github.com/vpacher volker@shutl.com
  162. 162. our
  163. 163. Watch the video with slide synchronization on InfoQ.com! http://www.infoq.com/presentations/shutl-neo4j- graph-db

×