# Dynamic query

**URL:** <https://community.neo4j.com/t/dynamic-query/7930>\
**Category:** Spring Data Neo4j & Neo4j-OGM\
**Created:** [June 9, 2019, 9:59am UTC](https://community.neo4j.com/t/dynamic-query/7930 "2019-06-09T09:59:56Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![toulouse.sabrina](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/toulouse.sabrina/32/2731_2.png) [@toulouse.sabrina](https://community.neo4j.com/u/toulouse.sabrina)\
**Post date:** [June 9, 2019, 9:59am UTC](https://community.neo4j.com/t/dynamic-query/7930/1 "2019-06-09T09:59:56Z")

</div>

Hi,

I would need to generate dynamic queries, to add some filters on conditions.  
Let say that my app handle Books and Authors. Books concerns one or more Theme.  
User can filter by Theme.  
So a query could be :

MATCH (b:Book)-[w:WRITEN]-(a:Author) MATCH (b:Book)-[c:CONCERNS]-(t:Theme {id : '1234'}) return b, w, a, c, t

Sometimes book's theme is unknown so a Book is not associated with any Theme.  
If user doesn't pick any filter, query would be :

MATCH (b:Book)-[w:WRITEN]-(a:Author) OPTIONAL MATCH (b:Book)-[c:CONCERNS]-(t:Theme) return b, w, a, c, t

In this case I can not go with @Query because of the optional filter and MATCH.  
From what I saw, queryDSL is not supported (yet?)

Is there any way to generate query with conditions, like we can do with Criteria for relational DB?

Many thx

---

<div class="post-metadata">

**Author:** ![Jiropole](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/jiropole/32/223_2.png) [@Jiropole](https://community.neo4j.com/u/Jiropole)\
**Post date:** [June 13, 2019, 5:03am UTC](https://community.neo4j.com/t/dynamic-query/7930/2 "2019-06-13T05:03:59Z")

</div>

A gloriously simple solution is to call a different @Repository method for each case, depending whether your `themeId` is null.

Otherwise, you could write your own function. See some docs on this here: [Spring Data Neo4j - Reference Documentation](https://docs.spring.io/spring-data/neo4j/docs/5.0.0.RELEASE/reference/html/#repositories.single-repository-behavior).

---

<div class="post-metadata">

**Author:** ![ofer.bar](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/ofer.bar/32/7850_2.png) [@ofer.bar](https://community.neo4j.com/u/ofer.bar)\
**Post date:** [August 4, 2020, 8:01am UTC](https://community.neo4j.com/t/dynamic-query/7930/3 "2020-08-04T08:01:39Z")

</div>

For whatever it is worth a year later, but might help others, there is a way to do dynamic cypher with the help of the APOC library.  
Consider this query:

@QUERY("CALL apoc.cypher.doIt({filterQuery}, {id: {id}}) " +  
"YIELD value AS v\_res RETURN x,y,z")  
myQuery(String filterQuery, Long id);

So filterQuery is dynamically built in the code and you can also pass into it parameters like {id} in this example.

The other options it to move away from Spring Data and use the Java driver directly or use a custom Neo4j plugin.

---

<div class="post-metadata">

**Author:** ![SulimanLab](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/sulimanlab/32/14640_2.png) [@SulimanLab](https://community.neo4j.com/u/SulimanLab)\
**Post date:** [October 24, 2020, 7:58am UTC](https://community.neo4j.com/t/dynamic-query/7930/4 "2020-10-24T07:58:02Z")

</div>

Sorry I am facing one issue with this approach,

```auto
    @Query("match (:Customer{username:$0})-[*1..2]->(i:Insight{id: $1}) " +
            "match (i)-[:OF_QUERY]->(query:Query{isLatest: true}) " +
            "CALL apoc.cypher.doIt("match (i:Insight) return i",null) YIELD value " +
            "return value")
    fun fetchInsightData(username: String, insightId: String): Flux<Insight>

```

spring boot refuses to cast the query to Flux even though I HAVE TESTED it in neo4j console and it works fine.

---

<div class="post-metadata">

**Author:** ![SulimanLab](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/sulimanlab/32/14640_2.png) [@SulimanLab](https://community.neo4j.com/u/SulimanLab)\
**Post date:** [October 24, 2020, 7:59am UTC](https://community.neo4j.com/t/dynamic-query/7930/6 "2020-10-24T07:59:57Z")

</div>

I found the solution for it , simply name the returned results from the inner query as so:

```auto
    @Query("match (:Customer{username:$0})-[*1..2]->(i:Insight{id: $1}) " +
            "match (i)-[:OF_QUERY]->(query:Query{isLatest: true}) " +
            "CALL apoc.cypher.doIt("match (i:Insight) return i as GG",null) YIELD value " +
            "return value.GG")
    fun fetchInsightData(username: String, insightId: String): Flux<Insight>

```

---

<div class="post-metadata">

**Author:** ![ofer.bar](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/ofer.bar/32/7850_2.png) [@ofer.bar](https://community.neo4j.com/u/ofer.bar)\
**Post date:** [December 3, 2020, 9:51am UTC](https://community.neo4j.com/t/dynamic-query/7930/7 "2020-12-03T09:51:32Z")

</div>

One small comment, you're using:

```auto
apoc.cypher.doIt

```

which uses a write transaction. It is not needed here and you can use a read transaction for better performance:

```auto
apoc.cypher.run

```
