kanpeki
kanpeki

Reputation: 445

Need help converting a Neo4j Cypher script to Gremlin

I can't figure out how to rewrite my Cypher script in Gremlin.

First we used the .Net Neo4j client to connect to our Neo4j database and run Cypher queries on it. Then we decided to add an abstraction layer and connect to a Gremlin server instead (which, for now, hosts the same Neo4j database). So now I need to translate our queries from Cypher to Gremlin and I am finding it rather difficult.

Here's one of them:

MATCH (pc:ProductCategory)-[:HasRootCategory]->(r:RootCategory)
WHERE NOT (:ProductCategory)-[]->(pc) 
AND pc.Id = r.RootId 
RETURN pc;

One of my failed attempts: g.V().match(as("pc").out("HasRootCategory").as("r"),as("pc").in().has('label', 'ProductCategory').count().is(0))).select("pc", "r").where("pc.Id", eq("r.RootId")).select("pc")

I found an example on stackoverflow using this 'match(as' construct, but it must be depracated or something, because I'm getting an error. Also, not sure how to compare properties with different names on nodes with different labels (I'm sure the 'where' is wrong...)

Any help would be appreciated.

Upvotes: 1

Views: 623

Answers (1)

Daniel Kuppitz
Daniel Kuppitz

Reputation: 10904

The following traversal should be equivalent:

g.V().hasLabel("ProductCategory").as("pc").
  not(__.in().hasLabel("ProductCategory")).
  out("HasRootCategory").as("r").
  where("pc", eq("r")).
    by("Id").
    by("RootId").
  select("pc")

Since you don't really need the r label, the query can be tweaked a bit:

g.V().hasLabel("ProductCategory").as("pc").
  not(__.in().hasLabel("ProductCategory")).
  filter(out("HasRootCategory").
         where(eq("pc")).
           by("Id").
           by("RootId"))

Last thing to mention: If a ProductCategory vertex can be connected to another ProductCategory vertex by only one (or more) specific edge label, that can lead nowhere else, it would be better to do:

g.V().hasLabel("ProductCategory").as("pc").
  not(inE("KnownLabelBetweenCategories")).
  filter(out("HasRootCategory").
         where(eq("pc")).
           by("Id").
           by("RootId"))

On a different note, match() is not deprecated. I guess you tried to run your traversal in Groovy and it just failed because you didn't use __.as() (as, among others, is a reserved keyword in Groovy).

Upvotes: 2

Related Questions