我有一个图表,其状态在时间上彼此跟随。每个状态都可以执行许多操作(0..n)和一些软件分配的一些建议(0..n)。
我可以像这样对cypher进行查询
start n=node:name(name="State")
match a<-[:hasAction]-s-[:isA]->n
s-[l?:hasRecommendation]->r
where l.likelihood>0.2
return distinct s.name as state, collect(a.name) as actions,
r.name as recommendation, l.likelihood as likelihood
order by s.name asc, l.likelihood desc
给了我一张这样的表
state | actions | recommendation | likelihood
--------------------------------------------------
State 1 | [a1,a2,a3] | a1 | 0.25
State 1 | [a1,a2,a3] | a4 | 0.05
State 2 | [a2,a3] | a3 | 0.56
State 2 | [a2,a3] | a2 | 0.34
State 2 | [a2,a3] | a1 | 0.15
如果我手动处理该表,我可以过滤这些结果,例如每个州只有前两个结果。这是耗时且非常不优雅的。
我的问题是,我从来不知道一个州有多少推荐,所以我不能在这里使用限制/跳过。理想情况下,我希望它只返回一定数量的状态(例如100),包括它们的最高建议 - 这个查询可以在0到100 * n行之间返回。
在密码中有没有更好的方法来实现这一目标?
答案 0 :(得分:0)
实现此目的的简单方法是选择具有建议的状态并将结果限制为100,然后通过动态计算每个状态的百分位数来检索这100个状态的前2个建议,如下所示,
start n=node:name(name="State")
Match s-[:isA]->n, s-[?:hasRecommendation]->r
With distinct s
Order by s.name
limit 100
Match s-[?:hasRecommendation]->r
With s, (count(r)-1.0) / count(r) as p
Match s-[l?:hasRecommendation]->r
With s, percentile_disc(l.likelihood, p) as m
start n=node:name(name="State")
match a<-[:hasAction]-s-[:isA]->n,
s-[l?:hasRecommendation]->r
where l.likelihood>= m
return distinct s.name as state, collect(a.name) as actions,
r.name as recommendation, l.likelihood as likelihood
order by s.name asc, l.likelihood desc
它有点冗长,但Cypher不支持嵌套函数进行聚合。所以我必须通过两个单独的查询得到“计数”和“百分位数”。