Skip to content
This repository was archived by the owner on Sep 3, 2021. It is now read-only.

Error when filtering with x_some #326

Closed
trondaal opened this issue Oct 18, 2019 · 0 comments
Closed

Error when filtering with x_some #326

trondaal opened this issue Oct 18, 2019 · 0 comments

Comments

@trondaal
Copy link
Contributor

trondaal commented Oct 18, 2019

Applying _some filter on relationships at levels below the root does not give the correct results with neo4j-graphql-js (but it behaves correctly using the plugin/java implementation).

The error can be recreated using the movie example data in neo4j and the following GraphQL schema:

type Movie {
  released: Int
  title: String
  tagline: String
  actors: [Person] @relation(name: "ACTED_IN", direction: IN)
  directors: [Person] @relation(name: "DIRECTED", direction: IN)
}

type Person {
  name: String
  date: String
  actedIn: [Movie] @relation(name: "ACTED_IN", direction: OUT)
  directorFor: [Movie] @relation(name: "DIRECTED"", direction: OUT)
}

The filtering on the root-level behaves as expected, but if you define a _some-filter on any children it will return false positives as exemplified by the following query where we ask for directors having directed movies featuring Tom Hanks:

{
  Person(filter: {directorFor_some: {actors_some: {name: "Tom Hanks"}}}) {
    name
    directorFor(filter: {actors_some: {name: "Tom Hanks"}}) {
      title
      actors {
        name
      }
    }
  }
}

The error is probably caused by incorrect variable being used in the ANY-test which can be seen in the generated query (parameter values have been replaced with literals to try it out in neo4j) :

MATCH (`person`:`Person`) 
WHERE (EXISTS((`person`)-[:DIRECTED]->(:Movie)) 
AND ANY(`movie` IN [(`person`)-[:DIRECTED]->(`_movie`:Movie) | `_movie`] 
WHERE (EXISTS((`movie`)<-[:ACTED_IN]-(:Person)) AND ANY(`person` IN [(`movie`)<-[:ACTED_IN]-(`_person`:Person) | `_person`] WHERE (`person`.name = "Tom Hanks"))))) RETURN `person` { .name ,directorFor: [(`person`)-[:`DIRECTED`]->(`person_directorFor`:`Movie`) 
WHERE (EXISTS((`person_directorFor`)<-[:ACTED_IN]-(:Person)) 
AND ANY(`person` IN [(`movie`)<-[:ACTED_IN]-(`_person`:Person) | `_person`] WHERE (`person`.name = "Tom Hanks"))) | person_directorFor { .title ,actors: [(`person_directorFor`)<-[:`ACTED_IN`]-(`person_directorFor_actors`:`Person`) | person_directorFor_actors { .name }] }] } AS `person`

The first ANY is correct, but for the second level ANY the set on the left side of the relationship represents the whole root-set rather than the filtered selection.

ANY(person IN [(movie)<-[:ACTED_IN]-(_person:Person)
should be:
ANY(person IN [(person_directorFor)<-[:ACTED_IN]-(_person:Person)

This is probably just a quick fix, but the code used to generate the statements is a bit difficult to figure out and I hope somebody that knows the code can look into it.

# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants