neo4j / cypher-dsl

A Java DSL (Builder) for the Cypher Query Language
http://neo4j.github.io/cypher-dsl
Apache License 2.0
196 stars 63 forks source link

Support for procedure call inside EXISTS subquery #694

Closed ikwattro closed 1 year ago

ikwattro commented 1 year ago

We have a need for being able to query a full text index in an EXISTS subquery which doesn't seem to be supported by the DSL.

Here is an example query :

MATCH path=(p:Person)-[:TRAVELED_TO]->(city)
WHERE EXISTS {
   CALL db.index.fulltext.queryNodes('City', 'ham*')
   YIELD node, score
   WITH *
   WHERE id(node) = id(city)
   RETURN node, score
}
RETURN path
michael-simons commented 1 year ago

    @Test // GH-694
    @SuppressWarnings("deprecation")
    void fullTextCallShouldWork() {

        var city = Cypher.anyNode("city");
        var node = Cypher.name("node");
        var score = Cypher.name("score");
        var statement = Cypher.match(Cypher.path("path").definedBy(Cypher.node("Person").named("p").relationshipTo(city, "TRAVELED_TO")))
            .where(
                Predicates.exists(
                    Cypher.call("db.index.fulltext.queryNodes").withArgs(Cypher.literalOf("City"), Cypher.literalOf("ham*"))
                        .yield(node, score)
                        .with(Cypher.asterisk())
                        .where(Functions.id(Cypher.anyNode(node)).eq(Functions.id(city)))
                        .returning(node, score)
                        .build()
                )
            ).returning(Cypher.name("path")).build();
        assertThat(statement.getCypher()).isEqualTo("""
            MATCH path = (p:`Person`)-[:`TRAVELED_TO`]->(city)
            WHERE EXISTS {
            CALL db.index.fulltext.queryNodes('City', 'ham*')
            YIELD node, score
            WITH *
            WHERE id(node) = id(city)
            RETURN node, score
            }
            RETURN path""".replace("\n", " "));
    }
ikwattro commented 1 year ago

too fast my friend, too fast !