I was using the GRAND stack starter and recently went through upgrading my packages and the Neo4j database to match the current versions identified in the GRAND starter kit.
This seems to have broken my most basic queries. I am creating a fairly simple demo database for exploration containing recipes. I have a node with a recipe on it that includes a name, instructions, and time.
This node also has relationships that indicate what kind of meal it is and how hard it is. You can see that below:
This returns just fine with my query on the front-end or in the Graphql Playground with the following query:
query($searchQuery: String = "baked") {
RecipesBySubstring(searchQuery: $searchQuery) {
name
time
instructions
ingredients {
name
quantity
}
mealtype {
type
}
difficulty {
value
}
}
}
The actual definition in my graphql-schema.js file looks like this:
RecipesBySubstring(searchQuery: String): [Recipe] @cypher(statement:
"MATCH (r:Recipe) WHERE toLower(r.name) CONTAINS toLower($searchQuery) OR toLower(r.time) CONTAINS toLower($searchQuery) RETURN r ORDER BY r.name ASC")
However as soon as I try to create a relationship that has properties, it fails to return any results using these exact queries. I create a relationship with this query:
MATCH (r:Recipe{name:"baked spaghetti"}),(i:Ingredient{name:"beef"})
CREATE (r)-[c:Contains{quantity:"1 pound"}]->(i)
RETURN r,i,c
And it adds it to the database just fine.
I also have defined my ingredients in my graphql-schema.js as follows:
type Ingredient {
name: String!
quantity: String @cypher(statement:"MATCH (:Recipe)-[c:Contains]-(this) RETURN q.quantity")
recipe: Recipe
}
Up until I upgraded things, these items were all working great. I had multiple recipes sharing ingredients I could query off of, querying a recipe would return all the ingredients and quantities as needed. You can see the previous iteration of the database in the following image and I can confirm this did return in the graphql playground and my front-end:
So I am kind of stumped what might have happened or if there is a new way I am suppose to be doing these things. I could roll back but since this is a learning process I want to keep my packages and databases up-to-date to go through these challenges.
The full error coming from the GraphQL Playground when attempting to query an node that has a relationship with properties is as follows:
{
"data": {
"RecipesBySubstring": null
},
"errors": [
{
"message": "Failed to invoke function `apoc.cypher.runFirstColumn`: Caused by: org.neo4j.cypher.internal.util.v3_4.SyntaxException: Variable `q` not defined (line 1, column 93 (offset: 92))",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"RecipesBySubstring"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"code": "Neo.ClientError.Procedure.ProcedureCallFailed",
"name": "Neo4jError",
"stacktrace": [
"Neo4jError: Failed to invoke function `apoc.cypher.runFirstColumn`: Caused by: org.neo4j.cypher.internal.util.v3_4.SyntaxException: Variable `q` not defined (line 1, column 93 (offset: 92))",
"",
" at captureStacktrace (E:\\Recipe Snap\\grand-stack-starter\\api\\node_modules\\neo4j-driver\\lib\\v1\\result.js:200:15)",
" at new Result (E:\\Recipe Snap\\grand-stack-starter\\api\\node_modules\\neo4j-driver\\lib\\v1\\result.js:73:19)",
" at Session._run (E:\\Recipe Snap\\grand-stack-starter\\api\\node_modules\\neo4j-driver\\lib\\v1\\session.js:116:14)",
" at Session.run (E:\\Recipe Snap\\grand-stack-starter\\api\\node_modules\\neo4j-driver\\lib\\v1\\session.js:95:19)",
" at _callee$ (E:\\Recipe Snap\\grand-stack-starter\\api\\node_modules\\neo4j-graphql-js\\dist\\index.js:80:28)",
" at tryCatch (E:\\Recipe Snap\\grand-stack-starter\\api\\node_modules\\regenerator-runtime\\runtime.js:62:40)",
" at Generator.invoke [as _invoke] (E:\\Recipe Snap\\grand-stack-starter\\api\\node_modules\\regenerator-runtime\\runtime.js:296:22)",
" at Generator.prototype.(anonymous function) [as next] (E:\\Recipe Snap\\grand-stack-starter\\api\\node_modules\\regenerator-runtime\\runtime.js:114:21)",
" at step (E:\\Recipe Snap\\grand-stack-starter\\api\\node_modules\\babel-runtime\\helpers\\asyncToGenerator.js:17:30)",
" at E:\\Recipe Snap\\grand-stack-starter\\api\\node_modules\\babel-runtime\\helpers\\asyncToGenerator.js:35:14"
]
}
}
}
]
}
The error is a Cypher syntax error. The query used in your
@cypher
directive onIngredient.quantity
in your GraphQL schema definition is incorrect, it is referring to a variableq
that has not been defined. Sincequantity
is a property on theContains
relationship and your query is bindingc
to that relationship your@cypher
directive query should beAlso, v1.0.1 of neo4j-graphql-js introduces better relationship type support so you don't have to use
@cypher
directives to access relationship properties, instead you can just define a relationship type: https://grandstack.io/docs/neo4j-graphql-js.html#relationships-with-properties