Search code examples
gremlintinkerpop3gremlin-server

TinkerPop: Gremlin revisiting visited edges


Sample Data:

enter image description here

Query to create sample data

g.addV("Test1").property("title", "A")
g.addV("Test2").property("title", "B")
g.addV("Test3").property("title", "C")
g.addV("Test4").property("title", "D")

g.V().has("Test1", "title", "A").addE("rel").to(g.V().has("Test2", "title", "B"))
g.V().has("Test2", "title", "B").addE("rel").to(g.V().has("Test3", "title", "C"))
g.V().has("Test3", "title", "C").addE("rel").to(g.V().has("Test4", "title", "D"))

Query:

  1. Find how A is connected to A

Expected answer: Not Connected

My Queries:

g.V().has("Test1", "title", "A").as("nodes")
.repeat(both().as("nodes"))
.emit(hasLabel("Test1")).hasLabel("Test1")
.limit(25)
.project("val").by(select(all, "nodes").unfold().values("title").fold())

Results (limit 25)

{'val': ['A', 'B', 'A']}
{'val': ['A', 'B', 'C', 'B', 'A']}
{'val': ['A', 'B', 'A', 'B', 'A']}
{'val': ['A', 'B', 'C', 'D', 'C', 'B', 'A']}
{'val': ['A', 'B', 'C', 'B', 'C', 'B', 'A']}
{'val': ['A', 'B', 'C', 'B', 'A', 'B', 'A']}
{'val': ['A', 'B', 'A', 'B', 'C', 'B', 'A']}
{'val': ['A', 'B', 'A', 'B', 'A', 'B', 'A']}
{'val': ['A', 'B', 'C', 'D', 'C', 'D', 'C', 'B', 'A']}
{'val': ['A', 'B', 'C', 'D', 'C', 'B', 'C', 'B', 'A']}
{'val': ['A', 'B', 'C', 'D', 'C', 'B', 'A', 'B', 'A']}
{'val': ['A', 'B', 'C', 'B', 'C', 'D', 'C', 'B', 'A']}
{'val': ['A', 'B', 'C', 'B', 'C', 'B', 'C', 'B', 'A']}
{'val': ['A', 'B', 'C', 'B', 'C', 'B', 'A', 'B', 'A']}
{'val': ['A', 'B', 'C', 'B', 'A', 'B', 'C', 'B', 'A']}
{'val': ['A', 'B', 'C', 'B', 'A', 'B', 'A', 'B', 'A']}
{'val': ['A', 'B', 'A', 'B', 'C', 'D', 'C', 'B', 'A']}
{'val': ['A', 'B', 'A', 'B', 'C', 'B', 'C', 'B', 'A']}
{'val': ['A', 'B', 'A', 'B', 'C', 'B', 'A', 'B', 'A']}
{'val': ['A', 'B', 'A', 'B', 'A', 'B', 'C', 'B', 'A']}
{'val': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A']}
{'val': ['A', 'B', 'C', 'D', 'C', 'D', 'C', 'D', 'C', 'B', 'A']}
{'val': ['A', 'B', 'C', 'D', 'C', 'D', 'C', 'B', 'C', 'B', 'A']}
{'val': ['A', 'B', 'C', 'D', 'C', 'D', 'C', 'B', 'A', 'B', 'A']}
{'val': ['A', 'B', 'C', 'D', 'C', 'B', 'C', 'D', 'C', 'B', 'A']}

Okay lets try dedup

g.V().has("Test1", "title", "A").as("nodes")
.repeat(both().as("nodes").dedup())
.emit(hasLabel("Test1")).hasLabel("Test1")
.project("val").by(select(all, "nodes").unfold().values("title").fold())

Result

{'val': ['A', 'B', 'A']}

There is exactly one edge between A and B. Then why is Gremlin traversing on the same edge? Am I writing the wrong query?

How Cypher Query behaves seems to be the correct way to be

MATCH p=((n:Test1)-[*]-(m:Test1)) RETURN p

enter image description here


Gremlin Server version: 3.3.1


Solution

  • Looks like all you want is non-cyclic paths:

    g.V().has("Test1", "title", "A").
      repeat(both().simplePath()).
        until(hasLabel("Test1")).
      path().
        by("title")