如何在Cypher查询结果的y列返回对应查询序列号?
修改后的Cypher查询方案
原查询的问题在于最后返回RANGE(0,4)作为y列,导致每一行都输出整个序号数组,而非对应单次查询的序列号。以下是两种修正方案:
方案一:使用窗口函数直接关联序号与执行时间
WITH ' MATCH (a:authors{name:"Lui Lis"})-[:`WROTE`]->(b:papers)-[:`REFERS_TO`]->(c:fieldsofstudy) RETURN c.name AS field_of_study, count(b) AS number_of_papers ' AS query UNWIND RANGE(0, 4) AS i WITH i, query, datetime.realtime().epochMillis AS start CALL apoc.cypher.doIt(query, NULL) YIELD value WITH i, datetime.realtime().epochMillis - start AS execTime WITH i, execTime, AVG(execTime) OVER() AS avg_time RETURN execTime AS x, i AS y, avg_time
关键修改点:
- 移除多余的
MAX()函数:单次查询仅生成一个执行时间值,无需取最大值 - 保留
i与execTime的关联关系,通过AVG(execTime) OVER()窗口函数计算所有查询的平均执行时间,确保每一行都能同时返回单次执行时间、对应序列号和平均时间 - 直接返回
i作为y列,实现每个查询对应唯一序列号
方案二:先收集结果再展开(兼容旧版Neo4j)
如果你的Neo4j版本不支持窗口函数,可以用这种方式:
WITH ' MATCH (a:authors{name:"Lui Lis"})-[:`WROTE`]->(b:papers)-[:`REFERS_TO`]->(c:fieldsofstudy) RETURN c.name AS field_of_study, count(b) AS number_of_papers ' AS query UNWIND RANGE(0, 4) AS i WITH i, query, datetime.realtime().epochMillis AS start CALL apoc.cypher.doIt(query, NULL) YIELD value WITH i, datetime.realtime().epochMillis - start AS execTime WITH collect({seq:i, time:execTime}) AS query_results, AVG(execTime) AS avg_time UNWIND query_results AS result RETURN result.time AS x, result.seq AS y, avg_time
关键修改点:
- 将每个查询的序列号和执行时间打包成对象,收集到集合中
- 展开集合时直接提取对应的序列号和时间,确保一一对应
- 提前计算好平均时间,展开后每一行都能复用该值
内容的提问来源于stack exchange,提问作者Gqueee
相关产品推荐
相关产品推荐

