Gremlin上的动态WITHIN子句

时间:2018-07-27 23:25:55

标签: azure-cosmosdb gremlin

我正在Azure Cosmo DB上使用Gremlin,但对它来说还很新。

我将尝试使事情变得简单,我的图是这样的:

我有两种类型的顶点:Identitiesinfos。信息是“边缘”身份的电子邮件和电话号码。

例如:

[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

1 个答案:

答案 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]