I've been trying to figure out a database backend for a personal webapp I've been working on. Due to the flexibility that I require in the data, a relational database isn't feasible and some form of document storage is likely. When I learned about graph databases, I felt that this would be perfect.
However, I've run into someone of an issue: I need to be able to define a 3-way relationship in some way. I haven't decided on a database yet, but I've been tinkering with Neo4j, so I'll use Cypher to describe the problem.
Essentially, I start out with this:
(a:N)-[r:E]->(b:N)
What I need is a way to relate multiple nodes to not only a and b, but also r. These other nodes are going to be storing different pieces of information about all 3. I decided that there are probably only two ways to handle this: store the relationship in its own node or store references to the nodes containing the information and create pseudo-edges. I figure that the former is probably a better idea giving us something more like this:
(a:N)<-[:E]-(r:R)->[:E](b:N)
(s:S)->(a)
(s)->(r)
(s)->(b)
So, now, this leads to an issue with querying the data. The whole point of using a graph database is being able to traverse the graph. If I do something like this, is there a way to recursively traverse between nodes of type N? What is the proper way of handling this? I've thought of several different ways of handling this, but all of them have their faults. Is there a specific graph database that supports this type of functionality natively?
UPDATE
With the original code, I was able to recursively traverse the nodes with this code:
MATCH (a:N)-[:E*]->(b:N)
RETURN a,b
However, once I pull the edge out into a hyperedge, I can't figure out if there is a way to be able to traverse the graph recursively to an undetermined depth because I would be alternating node types. I'm looking for something along the lines of
MATCH chain=((a:N)-[]->(r:R)-[]->(b:N))*
RETURN [nodes of type N along the chain]
If the answer is just to also create an edge between a and b while creating the hyper edge, then my question becomes: is there a good way to ensure that the edge and hyper edge are removed together? Basically, having both feels like a work-around rather than an actual solution.