我正在Azure Cosmo DB上使用Gremlin,但对它来说还很新。
我将尝试使事情变得简单,我的图是这样的:
我有两种类型的顶点:Identities
和infos
。信息是“边缘”身份的电子邮件和电话号码。
例如:
[012-123-12345 =(defines)=> Identity 1]
[axel@test.com =(defines)=> Identity 1]
[axel@work.com =(defines)=> Identity 1]
[987-654-213 =(defines=> Identity 2]
身份可以具有无限数量的电话号码或电子邮件。它可以有1个电子邮件和0个电话号码,反之亦然
我希望获得与另一个给定的身份顶点共享至少一个值(电话号码或电子邮件)的所有身份顶点。
我知道我可以在数组中选择给定标识(id :1234
)的所有值,如下所示:
g.V().hasLabel('identity').hasId('1234').in('defines').values('value')
我知道我可以使用给定的电子邮件和电话列表来选择所有身份顶点,例如:
g.V('info').has('value',within('123342356','test@email.com')).out('defines')
但是,我没有做类似的事情:
g.V('info').has('value',
within(g.V().hasLabel('identity').hasId('1234').in('defines').values('value')))
.out('defines')
感谢您的帮助,
Axel
答案 0 :(得分:2)
在询问有关Gremlin的问题时,最好包括一个Gremlin脚本,该脚本创建一些示例数据,因为它提供了很多上下文,并允许您获得经过全面测试且有效的遍历版本-像这样:
g.addV('identity').property('name','ident1').as('1').
addV('identity').property('name','ident2').as('2').
addV('identity').property('name','ident3').as('3').
addV('identity').property('name','ident4').as('4').
addV('identity').property('name','ident5').as('5').
addV('infos').property('info','321-333-1111').as('1111').
addV('infos').property('info','321-333-2222').as('2222').
addV('infos').property('info','321-333-3333').as('3333').
addV('infos').property('info','321-333-4444').as('4444').
addV('infos').property('info','321-333-1144').as('1144').
addV('infos').property('info','321-333-5555').as('5555').
addV('infos').property('info','1@here.com').as('1@').
addV('infos').property('info','2@here.com').as('2@').
addV('infos').property('info','3@here.com').as('3@').
addV('infos').property('info','4@here.com').as('4@').
addV('infos').property('info','35@here.com').as('35@').
addE('defines').from('1111').to('1').
addE('defines').from('2222').to('2').
addE('defines').from('3333').to('3').
addE('defines').from('4444').to('4').
addE('defines').from('1144').to('1').
addE('defines').from('1144').to('4').
addE('defines').from('5555').to('5').
addE('defines').from('1@').to('1').
addE('defines').from('2@').to('2').
addE('defines').from('3@').to('3').
addE('defines').from('4@').to('4').
addE('defines').from('35@').to('3').
addE('defines').from('35@').to('5').iterate()
因此,我从您的问题中了解到,您知道开始的“身份”,因此知道它定义的“信息”:
gremlin> g.V().has('identity','name','ident4').in('defines').values('info')
==>321-333-4444
==>321-333-1144
==>4@here.com
如果我们想知道还有谁可以分享这一点,我们只需沿着这些“定义”边缘来回浏览即可:
gremlin> g.V().has('identity','name','ident4').in('defines').out('defines').values('name')
==>ident4
==>ident4
==>ident4
==>ident1
您得到4个结果,因为有4个边被遍历-将它们累加到样本数据中。复制不是很好,所以:
gremlin> g.V().has('identity','name','ident4').
......1> in('defines').
......2> out('defines').
......3> dedup().
......4> values('name')
==>ident4
==>ident1
通常dedup()
并不是最好的方法。最好在遍历期间消除重复,对于您而言,这样做可能更好,因为您已经知道“起始身份”及其存在。我收集的您想要的是您不知道的其他“身份”顶点。
gremlin> g.V().has('identity','name','ident4').as('exists').
......1> in('defines').
......2> out('defines').
......3> where(neq('exists')).
......4> values('name')
==>ident1
请注意,当“身份”不共享“信息”时,我们将无法获得结果:
gremlin> g.V().has('identity','name','ident2').as('exists').
......1> in('defines').
......2> out('defines').
......3> where(neq('exists')).
......4> values('name')
gremlin>
如果您想查看匹配的数据,然后查看与之匹配的“身份”:
gremlin> g.V().has('identity','name','ident3').as('exists').
......1> in('defines').as('shared').
......2> out('defines').as('matched').
......3> where(neq('exists')).
......4> select('matched','shared').
......5> by('name').
......6> by('info')
==>[matched:ident5,shared:35@here.com]