Вот один из способов сделать это:
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))
В то время как первый был немного проще для чтения / отслеживания, я думаю, что второй лучше, потому что он хранит только список из двух подсчетов, тогда как первый хранит список всех вершин "бренда", которые были бы более память интенсивная, я думаю.
Еще один способ, предоставленный Дэниелом Куппицем, который использует groupCount()
интересным образом:
g.V().hasLabel('brand').
groupCount().
by(choose(inE('client_brand'),
constant('a'),
constant('b'))).
math('a/(a+b)')
Следующее решение, которое использует sack()
step, показывает, почему мы имеем math()
step:
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()
Если вы можете использовать лямбды, то:
g.V().hasLabel('brand').
union(where(inE('client_brand')).count(),
count())
fold().
map{ it.get()[0]/it.get()[1]}