neo4j-graphql-js
neo4j-graphql-js copied to clipboard
Incorrect results when using cypher directive on field returning relationship type
When custom Cypher is used for a field returning a relationship type, incorrect results are returned for node fields on the result. The properties on the relationship are correct, but the same, incorrect node is returned for every relationship.
This is what I think is going on:
In directedNodeTypeFieldOnRelationType
, '_relation' is added to the end of variable name. In customCypherField
, '_relation' is not being appended to nestedVariable
. Therefore the selection for the directed node will use an unbound name for the relation, so it matches every existing relationship.
Hey @danielmcmillan, could you show me an example of how you're trying to use a @cypher
directive on a field returning a relationship type? What are you wanting to return from its Cypher statement?
Are you doing something like this?
type NodeA {
relationshipTypeField: [RelationshipAB] @cypher(statement: "...")
}
type RelationshipAB {
from: NodeA
...
to: NodeB
}
type NodeB {
...
}
The GraphQL to Cypher translation processes that support using relationship types don't currently manage for the possibility of fields returning relationship types also having @cypher
directives on them. In a way, this would be like using a @cypher
directive on a field that already has a @relation
directive. Because of the@relation
directive, the field would already obtain translation support for being a relationship in Neo4j.
However, @cypher
directives can be used on relationship type fields. Do you think there might be a way to model your needs using something like:
type NodeA {
relationshipField: [RelationshipAB]
}
type RelationshipAB {
from: NodeA
computedField: String @cypher(statement: "")
to: NodeB
}
type NodeB {
...
}
Thanks @michaeldgraham,
The @cypher
directive is being used to filter the returned relationships by a field on a third node.
Something like this:
type NodeA {
relationshipTypeField(cId: String): [RelationshipAB]
@cypher(statement: "MATCH (this)-[r:RELATED_TO]-(:NodeB)-[]-(:NodeC {id: $cId}) RETURN r;")
}
type RelationshipAB @relation(name: "RELATED_TO") {
from: NodeA
...
to: NodeB
}
type NodeB {
relatedC: NodeC @relation(...)
...
}
type NodeC {
id: String
...
}
So then if I run this query:
query {
NodeA {
relationshipTypeField(cId: "x") {
NodeB {
relatedC {
id
}
}
}
}
}
Only relationships where NodeB->relatedC->id is "x" will be returned. The reason for the query is that NodeC represents a category, and NodeB is assigned to a category. We want to retrieve B by category from node A.
Thanks for the explanation, helps to understand why I should expect strange behaviour in this case. Since I am filtering the list of returned relationships I don't think a computed field on the relationship type will help. I'd be happy to hear if there is any better/alternate way to model cases like this though.
https://github.com/neo4j-graphql/neo4j-graphql-js/issues/608