apoc.do.when 中的 Neo4j 变量声明

问题描述 投票:0回答:1

我尝试在快速 api 请求中运行查询,使用 apoc.do.when 考虑与节点类型 Resource_Type 相关的名称字段的 2 个值:

@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)}")

当我运行此查询时出现错误,而 rn 在 apo 参数中正确定义

'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                                                                                                                                                                                                                                                                                                                                        ^}'

直接看到 Neo4j 请求:

MATCH (rt:Resource_Type {name: 'Server'})
CREATE (filter: Filter {id: '29a31db0-6149-4f79-ad0b-16f4efe66a71', name: 'AccessFilter'})                    
WITH rt, filter                    
UNWIND ['boosting', 'data'] AS tag_name
MATCH (tag: Tag {name: tag_name})
MERGE (filter)-[:INCLUDE_TAG]->(tag)
WITH rt, filter, ['boosting', 'data'] AS liste, 'Administrator' AS rn, 'Server' 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)-[:HAS_TAG]->(:Tag {name: tag})) ' +
     'WITH user, filter ' +
     'CREATE (filter)-[:FILTERS_USER]->(user) ' +
     'WITH filter ' +
     'MATCH (group: Group {name: rn}) ' +                   
     'CREATE (group)-[:USES_FILTER]->(filter) ' +                    
     'RETURN count(filter) 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, filter ' +
     'CREATE (filter)-[:FILTERS_RESOURCE]->(res) ' +
     'WITH filter ' +                    
     'MATCH (role: Role {name: rn}) ' +
     'CREATE (role)-[:USES_FILTER]->(filter) ' +
     'RETURN count(filter) AS created',
     {rt: rt, filter: filter, liste:liste, rn: rn, rtn: rtn}                    )
YIELD value                    
RETURN value. Created 
python neo4j fastapi neo4j-apoc
1个回答
0
投票

elseQuery
中,您需要将
rn
添加到两个
WITH
子句中。

这是一个更正后的版本(减去字符串连接噪音):

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
© www.soinside.com 2019 - 2024. All rights reserved.