Variable-length pattern matching

Is there a way to do variable-length pattern matching queries in dgraph?

Some examples (note that an asterisk (*) below denotes any number of hops along a path):

1. Find paths between node (A or B) and (C or D) but must include E
match p = (a)-[*]->(b) WHERE (a.name = 'A' OR a.name = 'B') AND
(b.name = 'C' OR b.name = 'D') AND any(x IN nodes(p) WHERE x.name='E') return p

2. Find paths between node (A or B) and (C or D) but must not include E
match p = (a)-[*]->(b) WHERE (a.name = 'A' OR a.name = 'B') AND
(b.name = 'C' OR b.name = 'D') AND all(x IN nodes(p) WHERE NOT x.name='E') return p

3. Find a random path between node (A or B) and (C or D)
match p = (a)-[*]->(b) WHERE (a.name = 'A' OR a.name = 'B') AND
(b.name = 'C' OR b.name = 'D') with collect(p) as allP, length(collect(p)) as totalP
return allP[toInteger(rand()*(totalP-1))]

4. Find paths that match a more complex pattern:
A - * - B - * - C - * - D - * -> E
{
	Fa as var(func: type(Node)) @filter(eq(name, "A") OR eq(name, "B") OR eq(name, "E"))
    
    query (func: uid(Fa), orderasc: name) @recurse {
      uid
      name
      To @filter(eq(name, "C") OR eq(name, "D"))
      To2 @filter(eq(name, "C") OR eq(name, "D"))
    }
}

Result

{
  "data": {
    "query": [
      {
        "uid": "0x4e2d",
        "name": "A",
        "To": [
          {
            "uid": "0x4e2e",
            "name": "D"
          }
        ]
      },
      {
        "uid": "0x4e2f",
        "name": "B",
        "To": [
          {
            "uid": "0x4e2e",
            "name": "D"
          }
        ],
        "To2": [
          {
            "uid": "0x4e2b",
            "name": "C"
          }
        ]
      },
      {
        "uid": "0x4e2c",
        "name": "E"
      }
    ]
  }
 }
{
	Fa as var(func: type(Node))
  @filter(eq(name, "A") OR eq(name, "B") OR eq(name, "E")) #You have to add E here.
    
    query (func: uid(Fa), orderasc: name) @filter(NOT eq(name, "E")) @recurse {
      uid
      name
      To @filter(eq(name, "C") OR eq(name, "D"))
      To2 @filter(eq(name, "C") OR eq(name, "D"))
    }
}

We don’t have any random func.

I’m not sure how to visualize this pattern, but I think that the recurse query can do it.

Other way to do it without the Recurse magic

{
	Fa as var(func: type(Node), orderasc: name)
  @filter(eq(name, "A") OR eq(name, "B") OR eq(name, "E"))

  GetB as var(func: uid(Fa)) @filter(eq(name, "B"))

  Gcd as var(func: uid(Fa)) @cascade {
     To @filter(eq(name, "C") OR eq(name, "D"))
  }
    query (func: uid(Gcd, GetB)) {
     uid
     name
     To {
       uid
       name
     }
  }
}

Dataset

{
   "set":[
      {
         "uid":"_:A",
         "name":"A",
         "To": [{"uid":"_:D"}],
         "dgraph.type":"Node"
      },
      {
         "uid":"_:B",
         "name":"B",
         "To": [{"uid":"_:C"}],
         "To2": [{"uid":"_:D"}],
         "dgraph.type":"Node"
      },
      {
         "uid":"_:C",
         "name":"C",
         "dgraph.type":"Node"
      },
      {
         "uid":"_:D",
         "name":"D",
         "dgraph.type":"Node"
      },
      {
         "uid":"_:E",
         "name":"E",
         "dgraph.type":"Node"
      }
   ]
}

Thanks, Michel. But I am still having trouble.
For case 1. above, I want the results to only include paths that include E and the paths may have more than 3 hops in them. Example results:
A
F
E
G
C

and

B
H
E
I
J
D