首页 > 解决方案 > 基于gremlin中的边缘属性查找百分比

问题描述

我需要找到为给定程序选择至少一个电话的收件人百分比。

我有这个架构。呼叫是作为某些程序的一部分向用户发出的,这些程序属于组织的一个单位

我的目标是:在作为程序 X 的一部分接听电话(已连接 = 是)的用户总数中,有多少人至少接听了一个电话(已接电话 = 是)(我需要找到百分比)

要查找至少收到 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。

我怎样才能编写一个查询来给我预期的比率?如何进行正确的遍历?

标签: graph-databasesgremlin

解决方案


您不需要两次遍历。我假设“连接”和“挑选”是同一边缘的属性。

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 岁以上并在 lop 工作的人的百分比

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

推荐阅读