Orientdb Gremlin:根据一行代码中的两个计数计算除法

Orientdb Gremlin:根据一行代码中的两个计数计算除法,orientdb,gremlin,Orientdb,Gremlin,我有两个计数,计算如下: 1) g.V().hasLabel('brand')。其中('client_brand').count()是(gt(0)).count() 2) g.V().hasLabel('brand').count() 我想得到一行代码,第一个数除以第二个数 这里有一种方法: g.V().hasLabel('brand'). fold().as('a','b'). math('a/b'). by(unfold().where(inE('client_brand')

我有两个计数,计算如下:

1) g.V().hasLabel('brand')。其中('client_brand').count()是(gt(0)).count()

2) g.V().hasLabel('brand').count()


我想得到一行代码,第一个数除以第二个数

这里有一种方法:

g.V().hasLabel('brand').
  fold().as('a','b').
  math('a/b').
    by(unfold().where(inE('client_brand')).count())
    by(unfold().count())
请注意,我将第一次遍历简化为
。其中(inE('client_brand')).count()
,因为您只关心至少有一条边的计数,所以无需将它们全部计数并进行比较

您还可以
union()
像:

g.V().hasLabel('brand').
  union(where(inE('client_brand')).count(),
        count())
  fold().as('a','b').
  math('a/b').
    by(limit(local,1))
    by(tail(local))
虽然第一个更容易阅读/理解,但我想第二个更好,因为它只存储两个计数的列表,而第一个存储所有“品牌”顶点的列表,我想这会占用更多内存

Daniel Kuppitz提供的另一种方法以一种有趣的方式使用
groupCount()

g.V().hasLabel('brand').
  groupCount().
    by(choose(inE('client_brand'),
                constant('a'),
                constant('b'))).
  math('a/(a+b)')
以下使用
sack()
步骤的解决方案显示了为什么我们有
math()
步骤:

g.V().hasLabel('brand').
  groupCount().
    by(choose(inE('client_brand'),
                constant('a'),
                constant('b'))).
  sack(assign).
    by(coalesce(select('a'), constant(0))).
  sack(mult).
    by(constant(1.0)). /* we need a double */
  sack(div).
    by(select(values).sum(local)).
  sack()
如果您可以使用lambdas,则:

g.V().hasLabel('brand').
  union(where(inE('client_brand')).count(),
        count())
  fold().
  map{ it.get()[0]/it.get()[1]} 

这就是我的工作原理:

g.V().limit(1).project('client_brand_count','total_brands')
.by(g.V().hasLabel('brand')
.where(__.inE('client_brand').count().is(gt(0))).count())
.by(g.V().hasLabel('brand').count())
.map{it.get().values()[0] / it.get().values()[1]}
.project('brand_client_pct')

嗨,斯蒂芬,谢谢你!不幸的是,当我尝试运行第一个方法时,我遇到了这个错误:groovy.lang.MissingMethodException:没有方法签名:org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal.math()适用于参数类型:(java.lang.String)值:[a/b]可能的解决方案:max(),max(groovy.lang.Closure),带有(groovy.lang.Closure)、max(java.util.Comparator)、each(groovy.lang.Closure)、each(groovy.lang.Closure)和each(groovy.lang.Closure)“brand”都有属性name、id、description和entityNameType,传入边缘“client_brand”和“client”都有相同的属性。
math()
步骤是在TinkerPop 3.3.0中引入的-也许您使用的是旧版本?daniel kuppitz提到了另一种使用
math()的方法,我刚刚将该步骤添加到了我的答案中,因为他不想再添加一个。如果使用
math()解决问题后事情仍然不起作用
如果您还有其他问题需要解决,我建议您提供一些示例数据:-下面是一个示例,您可以使用闭包,但它们应该是最后的手段,这就是为什么它们不是我或kuppitz建议的一部分。闭包会降低代码的可移植性,因为它们不能在所有环境中工作。我还认为如果你仍然打算使用LAMBDAS,你可以极大地减少你提出的解决方案的复杂性。我用一个更直接的LAMBDA解决方案再次更新我的答案。考虑做一个<代码> Prror()/<代码>,看看发生了什么变化。