如何优化下面的密码查询以实现分页

时间:2017-11-25 04:54:56

标签: neo4j cypher

@Component
class AutowiredTest {
    @Autowired
    fun constructor(env: Environment, appCtx: ApplicationContext) {
        println("ApplicationContext From Autowired" + appCtx.displayName)
        println(env.getProperty("server.port"))
    }

}

以上cypher用于获取所有评论,回复和喜欢该评论以及针对类似于用户Feed的用户进行审核。上述查询的输出是混乱的,并在应用层处理以及分页处理。 关于如何在查询本身中优化上述密码以及分页的任何建议都非常有用。

1 个答案:

答案 0 :(得分:0)

此查询的最大问题是您不使用聚合来收集独立的数据段,因此您需要在它们之间获取交叉产品,这会导致数据中的结果重复,很可能也会把你的罪名丢掉。

例如,在您的回访中,您将在评论和评论之间生成交叉产品。事实上,我真的建议在单独的查询中进行评论,否则(如果您收集评论),您将对每条记录进行相同的评论,这看起来很浪费。

这是一个替代查询,应该更适合您(现在,在查询中保留已收集的评论):

MATCH (user:Users {id: 1})
WITH user, [(user)<-[rv:REVIEW]-(rv_user:Users) | rv {.*, reviewer:rv_user}] as reviews
OPTIONAL MATCH (user)<-[:COMMENT]-(co:Comment)<-[ct_by:COMMENTED_BY]-(c_user:Users)
WITH reviews, co, ct_by, c_user
OPTIONAL MATCH (co)<-[:REPLY]-(r_co:Comment)<-[r_co_by:REPLIED_BY]-(r_co_user:Users)
WITH reviews, co, ct_by, c_user, r_co, r_co_by, r_co_user
ORDER BY ct_by.created_at DESC, r_co_by.created_at 
SKIP $skip LIMIT $limit
RETURN reviews, co, ct_by, c_user, r_co, r_co_user, size((co)<-[:LIKES]-()) AS co_likes, size((r_co)<-[:LIKES]-()) AS r_co_likes

我们在第一个WITH子句中使用模式理解和地图投影的组合来与评论者一起收集评论。

在我们完成与ct_byr_co_by的匹配后,我们可以使用SKIP和LIMIT进行分页,但您需要提供这些参数,并调用下一页的查询,跳过限制的倍数(如果更容易,可以相应地更改这些)。

我们在模式上使用size()函数来获取出现的次数,这更容易获得喜欢,特别是因为它从关系度数据中得到这个节点本身而不是必须扩展(假设所有:LIKES关系来自:用户)。

我们可以从这里进一步改进,例如,收集每条评论的回复数据:

MATCH (user:Users {id: 1})
WITH user, [(user)<-[rv:REVIEW]-(rv_user:Users) | rv {.*, reviewer:rv_user}] as reviews
OPTIONAL MATCH (user)<-[:COMMENT]-(co:Comment)<-[ct_by:COMMENTED_BY]-(c_user:Users)
WITH reviews, co, ct_by, c_user
OPTIONAL MATCH (co)<-[:REPLY]-(r_co:Comment)<-[r_co_by:REPLIED_BY]-(r_co_user:Users)
WITH reviews, co, ct_by, c_user, r_co, r_co_by, r_co_user
ORDER BY ct_by.created_at DESC, r_co_by.created_at 
SKIP $skip LIMIT $limit
WITH reviews, co, ct_by, c_user, r_co, r_co_user, size((co)<-[:LIKES]-()) AS co_likes, size((r_co)<-[:LIKES]-()) AS r_co_likes
RETURN reviews, co, ct_by, c_user, co_likes, collect(r_co {.*, replier:r_co_user, likes:r_co_likes}) as replies