【发布时间】:2019-03-21 18:03:50
【问题描述】:
我有两个计数,计算如下:
1)g.V().hasLabel('brand').where(__.inE('client_brand').count().is(gt(0))).count()
2)g.V().hasLabel('brand').count()
我想得到一行代码,结果是第一个计数除以第二个计数。
【问题讨论】:
我有两个计数,计算如下:
1)g.V().hasLabel('brand').where(__.inE('client_brand').count().is(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())
请注意,我将第一次遍历简化为 .where(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()
如果你可以使用 lambda,那么:
g.V().hasLabel('brand').
union(where(inE('client_brand')).count(),
count())
fold().
map{ it.get()[0]/it.get()[1]}
【讨论】:
math() 步骤是在 TinkerPop 3.3.0 中引入的 - 也许您使用的是旧版本? daniel kuppitz 提到了另一种使用math() step 的方法,我只是将其添加到我的答案中,因为他不想再添加一个。如果在您使用math() 解决问题后仍然无法正常工作,如果您还有其他问题需要解决,我建议提供一些示例数据:- 这是一个示例stackoverflow.com/questions/51388315/…
这对我有用:
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')
【讨论】:
profile(),看看发生了什么不同。