Отфильтруйте список, созданный обходом Gremlin и Groovy - PullRequest
0 голосов
/ 25 мая 2020

Я выполняю следующий обход:

g.V().has('Transfer','eventName','Airdrop').as('t1').
outE('sent_to').
inV().dedup().as('a2').
inE('sent_from').
outV().as('t2').
where('t1',eq('t2')).by('address').
outE('sent_to').
inV().as('a3').
select('a3','a2').
by('accountId').toList().groupBy { it.a3 }.collectEntries { [(it.key): [a2 : it.value.a2]]};

Итак, как вы можете видеть, я в основном выполняю обход, и в конце я использую groovy с collectEntries, чтобы агрегировать результаты вроде Мне они нужны, а в данном случае агрегатируется а3. Результаты выглядят так:

==>0xfe43502662ce2adf86d9d49f25a27d65c70a709d={a2=[0x99feb505a8ed9976cf19e757a9536117e6cdc5ba, 0x22019ad32ea3adabae68003bdefd099d7e5e3886]} 

(Это ХОРОШО, потому что количество значений в a2 не менее 2)

==>0x129e0131ea3cc16fe5252d7280bd1258f629f20f={a2=[0xf7958fad496d15cf9fd9e54c0012504f4fdb96ff]} 

(Это НЕ ХОРОШО, я хочу вернуть в моем списке только те комбинации, в которых есть как минимум 2 значения для a2)

Я пробовал использовать фильтры и дополнительный шаг where в самом обходе, но мне не удалось это сделать. Я не уверен, следует ли пропустить это, используя Groovy в моей последней строке. Любая помощь или ориентация будут очень благодарны

Ответы [ 2 ]

5 голосов
/ 26 мая 2020

Я не думаю, что вам нужно заглядывать в Groovy, чтобы получить нужный ответ. Было бы предпочтительнее сделать все это в Gremlin, тем более что вы собираетесь фильтровать результаты, которые могут дать некоторый выигрыш в производительности. У Gremlin есть собственный шаг group(), а также методы фильтрации результирующего Map:

g.V().has('Transfer','eventName','Airdrop').as('t1').
  out('sent_to').
  dedup().as('a2').
  in('sent_from').as('t2').
  where('t1',eq('t2')).by('address').
  out('sent_to').inV().as('a3').
  select('a3','a2').
    by('accountId').
  group().
    by('a3').
    by('a2').
  unfold().
  where(select(values).limit(local,2).count(local).is(gte(2)))

Идея состоит в том, чтобы построить ваш Map с group(), а затем разложить его на записи с unfold(). Вы фильтруете каждую запись с помощью where(), выбирая значения записи, которая представляет собой List из «a2», а затем подсчитывая элементы локально в этом List. Я использую limit(local,2), чтобы избежать ненужных итераций после 2, поскольку фильтр gte(2).

0 голосов
/ 26 мая 2020

Самый простой способ сделать это - использовать findAll {} .

.groupBy { it.a3 }
.findAll { it.value.a2.size() > 1 }
.collectEntries { [(it.key): [a2: it.value.a2]] }

, если некоторые a2 равны нулю, тогда value.a2 также оценивается как null и фильтрует результаты без необходимость явных нулевых проверок

...