1

我有一个图表,它的状态在时间上彼此跟随。每个状态都可以有许多发生的动作 (0..n) 和一些软件分配的一些建议 (0..n)。

我可以像这样对密码进行查询

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

如果我手动处理该表,我可以过滤这些结果,例如每个州只有前 2 个结果。这是耗时且非常不雅的。

我的问题是,我永远不知道一个州有多少建议,所以我不能在这里使用限制/跳过。理想情况下,我希望它只返回一组状态(例如 100 个),包括他们的最佳推荐——这个查询可以返回 0 到 100*n 行。

有没有更好的方法可以在密码中实现这一点?

4

1 回答 1

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 不支持用于聚合的嵌套函数。所以我必须通过两个单独的查询来获取“计数”和“百分位数”。

于 2013-08-21T13:40:41.127 回答