neo4j/cypher-dsl

Support for list variable as argument to `Functions.type`

Closed this issue · 2 comments

I am trying to generate this piece of cypher where p is a path in match statement like MATCH p = (s)-[r*1...10]->(t)

[x in relationships(p)| type(x)]

Here is what I am trying using the cypher-dsl library

     ...
        // Trying to build [x in relationships(p)| type(x)]
        var x = Cypher.name("x");
        var relationTypeCast = Cypher.listWith(x)
                .in(Functions.relationships(p))
                .returning(Functions.type(x)); // <===== Error here: Cannot cast Symbolic name to RelationShip
       ...

I cannot compile the code because the variable x is of type SymbolicName where as Functions.type expects a RelationShip as argument.

I have worked around my problem by rewriting the cypher without this piece of query, but I am curious to know how to write this in cypher-dsl.

PS: I am trying to find all paths between two nodes where the path contains a list of relations anywhere within the path. There are many ways to write such a cypher query and just the first one I thought of and tested on Neo4j Browser had this piece of query but I couldn't translate it to cypher-dsl because of this issue.

Thanks for using Cypher-DSL and raising this issue, @sathishkumar294 This will be added in 2023.2.0. Until then, here's also one workaround:

@Test // GH-630
void typesOfShouldWork() {

    var p = Cypher.path("p").definedBy(Cypher.node("Movie").relationshipFrom(Cypher.anyNode()).named("r"));
    var x = Cypher.name("x");
    var relationTypeCast = Cypher.listWith(x)
        .in(Functions.relationships(p))
        .returning(Functions.type(x));

    assertThat(Cypher.match(p).returning(relationTypeCast).build().getCypher())
        .isEqualTo("MATCH p = (:`Movie`)<-[r]-() RETURN [x IN relationships(p) | type(x)]");

    // Current workaround
    var relationTypeCast2 = Cypher.listWith(x)
        .in(Functions.relationships(p))
        .returning(Cypher.call("type").withArgs(x).asFunction());
    assertThat(Cypher.match(p).returning(relationTypeCast2).build().getCypher())
        .isEqualTo("MATCH p = (:`Movie`)<-[r]-() RETURN [x IN relationships(p) | type(x)]");
}

2023.2.0 is drop-in compatible with all 2023.0.0 versions for all normal use cases.
Would that be enough for your or do you need it in a 2022.9 release, too?

Hi, thanks for the reply. We think alike, my workaround is exactly the same as yours 😀
I can wait till the release of 2023.2.0.
Thanks 👍🏽