gremlin - 如何在没有变量的情况下在 AWS Neptune 中进行复杂的 Gremlin 查询?
问题描述
我正在使用不支持变量的 Amazon Neptune。然而,对于复杂的查询,我需要在多个地方使用一个变量。如何在不为相同数据查询两次的情况下做到这一点?
这是我要解决的问题:
给定一个 start
Person
,发现Persons
startPerson
通过knows
关系最多连接 3 个步骤。返回每个Person
的name
和distance
(1-3)。
由于 Neptune 不支持变量,我如何在没有变量的情况下在 Gremlin 中编写此查询?
解决方案
我看不出有什么理由需要变量来进行遍历,并且有很多方法可以得到答案。假设这个图:
g = TinkerGraph.open().traversal()
g.addV('person').property('name','A').property('age',20).as('a').
addV('person').property('name','B').property('age',21).as('b').
addV('person').property('name','C').property('age',22).as('c').
addV('person').property('name','D').property('age',19).as('d').
addV('person').property('name','E').property('age',22).as('e').
addV('person').property('name','F').property('age',24).as('f').
addE('next').from('a').to('b').
addE('next').from('b').to('c').
addE('next').from('b').to('d').
addE('next').from('c').to('e').
addE('next').from('d').to('e').
addE('next').from('e').to('f').iterate()
您可以执行以下操作:
gremlin> g.V().has('person','name','A').
......1> repeat(out().
......2> group('m').
......3> by(loops()).
......4> by(valueMap('name','age').by(unfold()).fold())).
......5> times(3).
......6> cap('m')
==>[0:[[name:B,age:21]],1:[[name:C,age:22],[name:D,age:19]],2:[[name:E,age:22],[name:E,age:22]]]
通过他们的名字找到一个特定的“人”顶点,在本例中为“A”,然后反复遍历out()
并分组您遇到的那些顶点,loops()
即您遍历的深度。在这种情况下,我使用valueMap()
它来提取您想要的属性。这times(3)
是搜索深度的限制。最后你cap()
从Map
我们的group()
. 该方法旨在为您提供一些基本结构,以了解如何完成此操作。您也许可以通过这种方式进一步完善它:
gremlin> g.V().has('person','name','A').
......1> repeat(out().
......2> group('m').
......3> by(loops())).
......4> times(3).
......5> cap('m').unfold().select(values).unfold().
......6> dedup().
......7> valueMap('name','age').by(unfold())
==>[name:B,age:21]
==>[name:C,age:22]
==>[name:D,age:19]
==>[name:E,age:22]
上面的示例从“m”中提取值Map
,删除重复项,dedup()
然后转换为您想要的结果。也许你一开始就不需要Map
(实际上我只是因为这个答案而想到它) - 你可以将store()
你的结果简单如下:
gremlin> g.V().has('person','name','A').
......1> repeat(out().store('m')).
......2> times(3).
......3> cap('m').unfold().
......4> dedup().
......5> valueMap('name','age').by(unfold())
==>[name:B,age:21]
==>[name:C,age:22]
==>[name:D,age:19]
==>[name:E,age:22]
您可能会考虑使用类似的东西simplePath()
来帮助避免一遍又一遍地重新遍历相同的路径。您可以在参考文档中阅读有关该步骤的信息。
推荐阅读
- testing - 如果某个测试失败,有没有办法保释套件?
- python - 通用视图中的成功消息不起作用
- php - Laravel / PHP - 高级多态关系
- r - 如何在调整后的折叠更改代码中使用 is.na 或 is.infinite 覆盖数据帧中的 NA?
- python-3.x - 带有 https 的 Kivy UrlRequest
- r - 使格子图中的某些线条不可见
- paypal - Paypal Sandbox Orders API - 捕获后资金未添加到余额中
- emacs - “选择已删除缓冲区”的“org-agenda-get-day-entries”错误
- html - 使用 Safari 在输入焦点上不需要的自动滚动到顶部
- javascript - 比较日期字符串