Unexpected Back behaviour

golang

#1

I’m trying to limit a given starting path to only those nodes which have a particular descendant at some set of possible descent levels. By descent level I just mean Out(someEdge) N times for level N.

For example, suppose I am trying to find people who either follow Fred, or follow someone who follows fred (levels 1 and 2), using a reduced version of the default testdata:

<alice> <follows> <bob> .
<bob> <follows> <fred> .
<charlie> <follows> <bob> .
<charlie> <follows> <dani> .
<dani> <follows> <bob> .
<dani> <follows> <greg> .
<emily> <follows> <fred> .
<fred> <follows> <greg> .

My approach is to tag the current nodes, go out via “follows” edges, then go back to the tagged nodes:

p := cayley.StartPath(store).
	Tag("MyTag")

p = p.Clone().
	Out("<follows>").
	Out("<follows>").
	Is(quad.String("<fred>")).
	Or(
		p.Clone().
			Out("<follows>").
			Is(quad.String("<fred>")),
	).
	Back("MyTag")

I would expect to get Alice, Bob, Charlie, Dani, and Emily. However, this only gets Alice, Charlie, and Dani, who are all two edges away. And if I go out twice inside the Or morphism, and once outside the Or morphism:

p := cayley.StartPath(store).
	Tag("MyTag")

p = p.Clone().
	Out("<follows>").
	Is(quad.String("<fred>")).
	Or(
		p.Clone().
			Out("<follows>").
                        Out("<follows>").
			Is(quad.String("<fred>")),
	).

I get Bob, and Emily who are only one edge away.

It seems that Back() just reverses the all the morphisms after the tag, and the Or morphsim’s Reversal method doesn’t seems to do anything.

Is this the expected behaviour? Should we expect the back method to do something to the path inside the Or morphism? What are some possible workarounds?


#2

I would say that most of the time Back is doing not what everyone expects.

Try to build the query in reverse instead:

fred := quad.String("<fred>")
p := cayley.StartPath(store, fred).In("<follows>").In("<follows>").Or(
   cayley.StartPath(store, fred).In("<follows>"),
)