Monday, 16 September 2013

IKEA wardrobes and Graphs: a perfect fit!

The idea for this blogpost was quite long in the making. We all know IKEA which is, like Neo4j, from Sweden. Most of us have delivered a daring attempt at assembling one of their furnitures. And most recently, even my 8- and 10-year old kids assembled their Swedish bedside tables themselves. Win!  

In the past year or so, ever so often does someone approached me to talk about how to use Neo4j in a manufacturing context. And every single time I thought to myself: what a great, wonderful fit! We all know “reality is a graph”, but when you look at manufacturing processes - and the way different process components interact - you quickly see that these wonderful flowchart diagrams, actually represent a network. A graph. And when you then start thinking about all the required parts and components that are required to deliver these processes - then it becomes even more clearer: the “bill of material” of manufactured goods can also, predictably, be represented as a graph.


So there you have it. Manufacturing processes and bills or materials can be represented as a graph. And IKEA cupboards, wardrobes, tables, beds, stools - everywhere. How to make the match?

Part 1: PAX wardrobes come in parts



I spent some time looking for the Bills of Material (BoM) for some IKEA furniture - but could not find it. So what do you do? You download a couple of instruction manuals from their website, and you do it yourself. I took two wardrobes of the “PAX system”: DeepPax and ThinPax. Essentially they are almost the same wardrobes - the only thing different is the depth of the wardrobe. In my model, both of them would become “ShopArticles”, and after having browsed through the instruction manuals in some detail, I came up with the BoM myself. If found that there were going to be three kinds of things in my IKEA “box of joy”:
  • Components: these are the smaller components (screws, nails, hinges, …) of the wardrobe
  • StructureComponents: these are the larger, structural components (the side-, top-, bottom- and rear panels)
  • the Tools: which IKEA nicely spells out for you as you would need them during the assembly process.


You can take a look at the model used in the figure.



In the spreadsheet that I created to create a graph out of this, you will see all of these parts listed, the relationships with the ShopArticle, as well as the Cypher statements that I generated using the spreadsheet method to create the neo4j database.


In the database, you can easily see that the part lists for DeepPAX and ThinPAX are very, very similar. The only major structural difference is in the bottom support section of the wardrobe: the DeepPAX has front AND bottom support StructureComponents, the ThinPAX only has a front StructureComponent. Tiny detail, explained by gravity.


Part 2: PAX wardrobes require a process



Once I had the parts, I turned to the second part of my quest: creating a graph representation of the process steps that one should follow to assemble the wardrobes. My wife claims that this was probably the first time that a really read an IKEA manual, but the result is that I created a second new part to the graph model above, that contains
  • Process steps that execute the different actions to assemble the wardrobe
  • The components/structure components/tools that are used in every step
  • The sequence of these steps, and how this completes the construction of the wardrobe


Reading the manual start to finish (ouch) I actually found out that there are 23 steps to complete the wardrobes - and the steps are largely the same for DeepPAX and ThinPAX. There were only a couple of parts that were slightly different - obviously because of the slightly different part list. And so I was able to create a complete model of the process flow: take a look at the complete model above, knowing that I have only drawn out one (orange) process step below - and in reality there will be 1 starting process step, 1 completing process step, and 21 “orange” process steps in between.

Part 3: walking and querying the IKEA PAX graph



As I mentioned above, I created the database “the spreadsheet way”. It’s not a very big graph anyway - all I am trying to do here is to point out how easily you could model these types of problems as graphs.



You can download the database from over here. As usual, one of the first nice things you can do now, is “take a walk on your data”, by just browsing the graph in the neo4j webadmin.


Then of course the next and more interesting step was to start querying the dataset using Cypher. Here are some of the queries that I came up with (thanks Michael) - no doubt you can come up with better/more interesting ones.


Part 4: query-fun with Cypher



I have put all of the queries together in a little text file that you can download as well.


// Give me the number of components for every ShopArticle


START
shoparticle=node:node_auto_index(type="ShopArticle")
MATCH
(shoparticle)-[:USES_COMPONENT]->(component)
RETURN shoparticle.name AS article, count(*) AS numberofcomponents;


// Give me the number of structural components for every ShopArticle


START
shoparticle=node:node_auto_index(type="ShopArticle")
MATCH
(shoparticle)-[:USES_STRUCTURE_COMPONENT]->(component)
RETURN shoparticle.name AS article,
      count(*) AS numberofstructurecomponents;


// Give me the total partlist for a shoparticle


START
shoparticle=node:node_auto_index(type="ShopArticle")
match
component<-[:USES_STRUCTURE_COMPONENT|USES_COMPONENT]-shoparticle
return
shoparticle.name as Item, component.name as Component, component.type
order by component.type;


// Give me the list of shared components by different shoparticles


START
deeppax=node:node_auto_index(name="DeepPAX"),
thinpax=node:node_auto_index(name="ThinPAX")
MATCH
(deeppax)-[:USES_COMPONENT|USES_STRUCTURE_COMPONENT]->(component)
       <-[:USES_COMPONENT|USES_STRUCTURE_COMPONENT]-(thinpax)
RETURN
DISTINCT component.id, component.name, component.type
ORDER BY component.name;


// Give me the list of components that are NOT shared by different shoparticles


START
deeppax=node:node_auto_index(name="DeepPAX"),
thinpax=node:node_auto_index(name="ThinPAX")
MATCH
p = (deeppax)-[?:USES_COMPONENT|USES_STRUCTURE_COMPONENT]->(component)<-[?:USES_COMPONENT|USES_STRUCTURE_COMPONENT]-(thinpax)
WHERE p = null
RETURN
DISTINCT component.id, component.name, component.type
ORDER BY component.id;


An alternative way of doing the same query could be:


START
deeppax=node:node_auto_index(name="DeepPAX"),
thinpax=node:node_auto_index(name="ThinPAX")
MATCH
(deeppax)-[:USES_COMPONENT|USES_STRUCTURE_COMPONENT]->(component)
WHERE NOT ((component)<-[:USES_COMPONENT|USES_STRUCTURE_COMPONENT]-(thinpax))
RETURN
DISTINCT component.id, component.name, component.type
ORDER BY component.id;



// Give me the number of installation steps for every ShopArticle


START
shoparticle=node:node_auto_index(type="ShopArticle")
MATCH
p = (shoparticle)-[:STARTS_CONSTRUCTION]->(step)-[:CONTINUES_PROCESS*]->(step2)-[:COMPLETES_CONSTRUCTION]->(shoparticle)
RETURN
shoparticle.name AS Item, (length(p)-1) AS NumberOfSteps;


You can see some of the  results below. First: the number of components and the number of structurecomponents in the different shoparticles:




Then: the partlist for the different shoparticles:


You will have to play with some of the other queries to see the results :)) ...

What I learnt from this exercise



Well, couple of things:
  • IKEA wardrobes are complicated. I am sure that I will build some more of these  in the future, and my plan today is to *rtfm thoroughly*  before going in with my heavy tools.
  • Part lists, bills of materials and the likes are excellent for graph applications. I only used two wardrobes in my example here - but imagine what would happen if I really was IKEA, and if I would start putting all my wardrobes, all my products into one giant product catalog with all of the containing parts. Imagine the dependency analysis queries I could do: what would happen if one particular screw would run out of stock? What products would be impacted by that? Really, I mean **really** interesting stuff that would be tremendously difficult to do in a relational system.
  • Processes - as you can already see from many of the flowchart examples - are graphs. Again, same remark: imagine if I had more than two processes, and I would want to see the interconnectedness between these processes? What if I wanted to build these two wardrobes at the same time, with only one set of tools? Where would I see the bottlenecks? Would there be any constraints on tools or the likes?


In short, I think this blogpost aims to do nothing but to get you thinking about how to model and implement your manufacturing problems in a new, innovative way - without many of the constraints of the relational model. I hope that came across, and I hope you found it as useful as I found it fun to write.


All the best,


Rik

Thursday, 12 September 2013

Lots of graphyness in Benelux happening in October

Just thought I would quickly summarize some of the great activities that are happening around neo4j and graphs in Belgium and the Netherlands in October:

For any of these, please register on the eventbrite/meetup links above, and let's make these wonderful events.