在gremlin中基于边缘属性查找百分比

时间:2019-08-02 04:23:03

标签: graph-databases gremlin

我需要找到为给定程序选择了至少一个呼叫的接收者的百分比。

我有this模式。作为某些程序的一部分,向用户进行调用,这些程序属于 unit 组织

我的目标是:作为程序X的一部分,在接听电话(已接通=是)的用户总数中,有多少人选择了至少一个电话(接听=是)(我需要找到%)< / p>

要查找至少收到1个电话的收件人列表:

g.V().hasLabel("User").filter(inE().has("connected","yes").filter(outV().in().has("Program","name","X")).count().is(gte(1))).count()

类似地,查找至少接听1个电话的收件人列表:

g.V().hasLabel("User").filter(inE().has("picked","yes").filter(outV().in().has("Program","name","X")).count().is(gte(1))).count()

我知道我需要采用这些值的比率。经过研究,我意识到需要进行两次并行遍历,并使用math()来找到百分比。我尝试了以下查询:

g.V().hasLabel("User").as("a","b").
math("a/b * 100").
by(filter(inE().has("picked","yes").
filter(outV().in().has("program","name","X")).count().is(gte(1)))
.count()).
by(filter(inE().has("connected","yes").
filter(outV().in().has("program","name","X")).count().is(gte(1)))
.count())

但是出现以下错误:

Division by zero!
Type ':help' or ':h' for help.
Display stack trace? [yN]

我认为正在发生的情况是此查询正在为每个用户(不是我的预期)以及从未在程序“ X”下收到任何呼叫的用户生成百分比,分母可以理解为0。

如何编写查询以给出预期的比率?如何进行正确的遍历?

1 个答案:

答案 0 :(得分:1)

您不需要两次遍历。我假设“已连接”和“已拾取”是同一条边的属性。

g.withSack(0).
  V().hasLabel("User").
  inE().has("connected","yes").
  sack(sum).
    by(choose(has("picked","yes"),
                constant(1),
                constant(0))).
  outV().in().has("Program","name","X").
  union(sack().sum().project("picked"),
        count().project("called")).
  unfold().
  group().
    by(keys).
    by(select(values)).
  math('picked/called')

要防止NPE在没有连接的情况下,您可以将math步骤替换为:

choose(unfold(),
         math('picked/called'),
         constant(0))

这将使0为默认/后备返回值。

跳转到现代图形以显示示例。

年龄在30岁以上并且在棚子里工作过的人的百分比

gremlin> g.V().has("name","lop").in().valueMap()
==>[name:[marko],age:[29]]
==>[name:[josh],age:[32]]
==>[name:[peter],age:[35]]
gremlin> g.withSack(0).
......1>   V().hasLabel("person").
......2>   outE("created").
......3>   sack(sum).
......4>     by(choose(outV().has("age",gt(30)),
......5>                 constant(1),
......6>                 constant(0))).
......7>   inV().has("software","name","lop").
......8>   union(sack().sum().project("oldGuys"),
......9>         count().project("total")).
.....10>   unfold().
.....11>   group().
.....12>     by(keys).
.....13>     by(select(values)).
.....14>   math('oldGuys/total')
==>0.6666666666666666