I try to run a query in a fast api request, using apoc.do.when to take in consideration 2 value of the name field related to the node type Resource_Type:
@app.post("/filter/create", status_code=201)
def create_filter(request: FilterCreateRequest):
filter_id = str(uuid.uuid4())
try:
with get_driver() as driver:
with driver.session() as session:
result = session.run(f"""
MATCH (rt:Resource_Type {{name: '{request.resource_type_name}'}})
CREATE (filter:Filter {{id: '{filter_id}', name: '{request.name}'}})
WITH rt, filter
UNWIND {request.tag_list} AS tag_name
MATCH (tag:Tag {{name: tag_name}})
MERGE (filter)-[:{config['Filter']['Tag']}]->(tag)
WITH rt, filter, {request.tag_list} AS liste, '{request.resource_name}' AS rn, '{request.resource_type_name}' AS rtn
WITH rt,filter, liste, rn, rtn
CALL apoc.do.when(
rt.name = 'User',
'MATCH (user:User) ' +
'WHERE ALL(tag IN liste WHERE (user)-[:{config['User']['Tag']}]->(:Tag {{name: tag}})) ' +
'WITH user, filter ' +
'CREATE (filter)-[:{config['Filter']['User']}]->(user) ' +
'WITH filter ' +
'MATCH (group:Group {{name: rn}}) ' +
'CREATE (group)-[:{config['Group']['Filter']}]->(filter) ' +
'RETURN count(filter) AS created',
'MATCH (res:Resource)-[:{config['Resource']['Resource_Type']}]->(:Resource_Type {{name: rtn}}) ' +
'WHERE ALL(tag IN liste WHERE (res)-[:{config['Resource']['Tag']}]->(:Tag {{name: tag}})) ' +
'WITH res, filter ' +
'CREATE (filter)-[:{config['Filter']['Resource']}]->(res) ' +
'WITH filter ' +
'MATCH (role:Role {{name: rn}}) ' +
'CREATE (role)-[:{config['Role']['Filter']}]->(filter) ' +
'RETURN count(filter) AS created',
{{rt: rt, filter: filter, liste:liste, rn: rn, rtn: rtn}}
)
YIELD value
RETURN value.created
""")
created_count = result.single()
if created_count > 0:
return {"message": "Filter created and linked successfully", "filter_id": filter_id}
else:
return {"message": "Resource_Type not found or invalid resource_id"}
except Exception as e:
raise HTTPException(status_code=400, detail=f"An error occurred: {str(e)}")
there the error I got when I'm running this query whereas rn is properly define in the apo parameters
'An error occurred: {code: Neo.ClientError.Procedure.ProcedureCallFailed} {message: Failed to invoke procedure `apoc.do.when`: Caused by: org.neo4j.exceptions.SyntaxException: Variable `rn` not defined (line 1, column 328 (offset: 327))\n" WITH $`filter` as `filter` , $`rt` as `rt` , $`liste` as `liste` , $`rn` as `rn` , $`rtn` as `rtn` MATCH (res:Resource)-[:IS_A]->(:Resource_Type {name: rtn}) WHERE ALL(tag IN liste WHERE (res)-[:HAS_TAG]->(:Tag {name: tag})) WITH res, filter CREATE (filter)-[:FILTERS_RESOURCE]->(res) WITH filter MATCH (role:Role {name: rn}) CREATE (role)-[:USES_FILTER]->(filter) RETURN count(filter) AS created"\n ^}'
there the sight of the neo4j request directly :
MATCH (rt:Resource_Type {name: 'Server'})
CREATE (filtr: Filter {id: '29a31db0-6149-4f79-ad0b-16f4efe66a71', name: 'AccessFilter'})
WITH rt, filtr
UNWIND ['boosting', 'data'] AS tag_name
MATCH (tag: Tag {name: tag_name})
MERGE (filtr)-[:INCLUDE_TAG]->(tag)
WITH rt, filtr,'Administrator' AS rn, ['boosting', 'data'] AS liste, 'Server' AS rtn
WITH rt,filtr, rn,liste, rtn
CALL apoc.do.when(
rt.name = 'User',
'MATCH (user: User)
WHERE ALL(tag IN liste WHERE (user)-[:HAS_TAG]->(:Tag {name: tag}))
WITH user, filtr, rn
CREATE (filtr)-[:FILTERS_USER]->(user)
WITH filtr , rn
MATCH (group: Group {name: rn})
CREATE (group)-[:USES_FILTER]->(filtr)
RETURN count(filtr) AS created ',
'MATCH (res:Resource)-[:IS_A]->(:Resource_Type {name: rtn})
WHERE ALL(tag IN liste WHERE (res)-[:HAS_TAG]->(:Tag {name: tag}))
WITH res, filtr, rn
CREATE (filtr)-[:FILTERS_RESOURCE]->(res)
WITH filtr, rn
MATCH (role: Role {name: rn})
CREATE (role)-[:USES_FILTER]->(filtr)
RETURN count(filtr) AS created ',
{rt: rt, filtr: filtr, liste:liste, rn: rn, rtn: rtn} )
YIELD value
RETURN value. Created
In your elseQuery
you need to add rn
to both of the WITH
clauses.
Here is a corrected version (minus the string concatenation noise):
MATCH (res:Resource)-[:IS_A]->(:Resource_Type {name: rtn})
WHERE ALL(tag IN liste WHERE (res)-[:HAS_TAG]->(:Tag {name: tag}))
WITH res, filter, rn
CREATE (filter)-[:FILTERS_RESOURCE]->(res)
WITH filter, rn
MATCH (role:Role {name: rn})
CREATE (role)-[:USES_FILTER]->(filter)
RETURN count(filter) AS created