0
votes

Let's say my graph is a series of steps, which connect to one another in a procedure. Is there a best/recommended way to model this in a graph?

I can think of two different approaches:

Number one:

CREATE [s1:Step]-[r1:step { procedure: "Foo" }]->[s2:Step]

In this method, I need to examine properties of the step relationship to reconstitute an entire procedure. Just follow all the relationships labeled procedure: Foo.

Number two:

CREATE (p:Procedure {name: "Foo"}), 
       (s1:Step), (s2:Step), 
       p-[:step { sequence: 0 }]->s1, 
       p-[:step { sequence: 1 }]->s2;

This creates an actual first-class procedure "node" but buys me the problem of having to specify the sequence number so I know which order the steps should be in.

This problem must have been solved a dozen times before though. Is there a better/best pattern for modeling this as a graph?

2

2 Answers

2
votes

The following approach might be suitable for your needs. It creates a chain of Step nodes rooted at a Procedure node.

The Procedure node also has a LAST_STEP relationship to point to the currently last Step node, in an attempt to enable more performant appending of new Step nodes. But there might be a more efficient way to handle this.

A possible drawback to this approach is that you cannot parametrize the number of steps in #4.

  1. To initiate the chain of steps for a procedure, starting with the first step:

    CREATE (p:Procedure {name: "Foo"})-[:LAST_STEP]->(s:Step {...}), (p)-[:NEXT_STEP]->(s);
    
  2. To add a step to the end of a chain:

    MATCH (p:Procedure {name: "Foo"})-[ls:LAST_STEP]->(s)
    DELETE ls
    CREATE (p)-[:LAST_STEP]->(s1:Step {...})
    CREATE (s)-[:NEXT_STEP]->(s1);
    
  3. To get the 1st step for a chain (or null if there are no steps):

    MATCH (p:Procedure {name: "Foo"})-[:NEXT_STEP]->(s)
    RETURN s;
    
  4. To get the 3rd step for a chain, or null if there are fewer than 3 steps (you can replace 3 with any number):

    MATCH (p:Procedure {name: "Foo"})-[:NEXT_STEP*3]->(s)
    RETURN s;
    
  5. To get the step after step s (assuming we already have s somehow):

    ...
    MATCH (s)-[:NEXT_STEP]->(s1)
    RETURN s1;
    
  6. To get all the steps in a chain, in order:

    MATCH (p:Procedure {name: "Foo"})-[ns:NEXT_STEP*]->(s)
    RETURN s ORDER BY length(ns);
    
1
votes

i think index searching is not a good idea its better to use label scanning we can`t use several labels on relations and have 64k relation type limits if your need dont exceed this limitations u can use something like this

a-[:STEP_FOO]-b-[STEP_BAR]-c