Возвращает определенные вершины и то, имеют ли они общее ребро с определенной вершиной

Я пытаюсь смоделировать отношения подписчиков между определенными пользователями в своем приложении:

пользователь ---- следует ---- пользователь

(думаю, Twitter)

Учитывая набор userIds, мне нужно вернуть все эти пользовательские вершины и логическое значение, если конкретный пользователь (currentUser) имеет follows край для этих пользователей. Поэтому мне нужно знать, подписан ли currentUser на каждого из этих пользователей:

user1: правда

user2: правда

user3: ложь

user4: правда

Я застрял в том, как получить этот статус подписки. Если я верну каждую пользовательскую вершину так:

currentUser = g.V(1); g.V().hasLabel("appUser").or(__.has("userId","123869681319429"), __.has("userId","103659593341656")).valueMap();

Какой была бы эффективная команда, чтобы определить, есть ли у каждого из них входящее follows ребро от currentUser?

TitanDB 1.0.0 работает на DynamoDB.

Изменить - Добавление моего полного рабочего обхода:

g.V().hasLabel('appUser').or(__.has('cId', '1232'),__.has('cId', '1116')).group().by().by(__.in('follows').hasId(hasLabel('appUser').has('pId', 'd13dfa6').id()).count())

Изменить 2 - я переписал этот обход, чтобы лучше фиксировать нужные мне данные, используя as() и select(). Оставляем здесь для справки:

g.V().hasLabel('appUser').or(__.has('cId', '1232'),__.has('cId', '1116')).as('user','followCount').select('user','followCount').by(__.valueMap()).by(__.in('follows').hasId(hasLabel('appUser').has('pId', 'd13dfa6').id()).count())


person Fook    schedule 25.03.2016    source источник


Ответы (1)


Вот один из способов сделать это. Предположим, что этот пример графика:

gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> vUser1 = graph.addVertex(id,1)
==>v[1]
gremlin> vUser2 = graph.addVertex(id,2)
==>v[2]
gremlin> vUser3 = graph.addVertex(id,3)
==>v[3]
gremlin> vUser1.addEdge('follows',vUser2)
==>e[0][1-follows->2]
gremlin> vUser3.addEdge('follows',vUser3)
==>e[1][3-follows->3]

Приведенный выше фрагмент кода демонстрирует, что у вас будет вершина «текущего пользователя» и вершины пользователей, которых вы хотите сравнить с этим текущим пользователем, чтобы увидеть, есть ли какие-либо отношения подписки. Учитывая это предположение, вы можете подойти к этому следующим образом:

gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:3 edges:2], standard]
gremlin> g.V(vUser2,vUser3).group().by().by(__.in("follows").hasId(vUser1.id()).count())
==>[v[2]:1, v[3]:0]

В этом случае вы перебираете список пользовательских вершин, с которыми хотите сравнить, а затем группируете их. В результате обхода будет выведено Map, где значение больше 0 представляет связь "следование", а значение нуля представляет собой противоположность связи "отсутствие следования". Итак, в приведенном выше примере пользователь 1 следует за 2, но не за 3.

person stephen mallette    schedule 26.03.2016
comment
Спасибо, это хорошо работает. Я добавил свой полный рабочий обход к исходному вопросу. Как видите, я ищу пользователей по идентификатору, а затем использую вашу логику. Можно ли вернуть определенные свойства искомых пользователей (firstName, lastName и т. Д.) Вместо всех объектов? Я не уверен, где можно указать эти свойства. - person Fook; 04.04.2016
comment
Первый модулятор by() определяет ключ для карты. Вы можете передать ему свойство для извлечения или, может быть, valueMap() на основе Traversal для извлечения свойств. Я думаю, что Map равенство по-прежнему позволит ему правильно сгруппироваться с Map в качестве ключа. Вы также можете обработать результат, чтобы преобразовать Vertex ключи во все, что захотите. Вариантов много. - person stephen mallette; 04.04.2016
comment
Передача отдельного свойства в by() отлично работает, но я полагаю, что таким образом я могу вернуть только одно свойство. Я пробовал .by(__.valueMap()), но это дает org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet cannot be cast to org.apache.tinkerpop.gremlin.structure.Element. Я правильно передаю? Я стараюсь избегать пост-обработки, если это возможно из соображений производительности. - person Fook; 04.04.2016