graph-databases - gremlin中同种顶点(共享相同标签的顶点)之间遵循一定的关系(带有一定标签的边)
问题描述
我的任务是为可视化 Neptune Graph 数据库的前端应用程序编写查询。假设第一个顶点是项目,而第二个顶点是用户。用户可以创建项目。有项目到项目的关系来显示从另一个项目派生的项目,就像从原始媒体剪辑中剪下的媒体剪辑的情况一样。创建的第一组项目应该在一个顶点中创建,例如SERVER
它们在 UI 中分组的一个顶点。
以下是要求:
Filtering on a vertex shows the full graph for that vertex:
(1) Follow all ITEM - ITEM relationships
(2) Show any ITEM - USER relationships up to 1 hop (i.e. further ITEMs linked to a USER not shown already by (1) should not be displayed)
这是图表的可视化表示。
https://drive.google.com/file/d/1YNzh4wbzcdC0JeloMgD2C0oS6MYvfI4q/view?usp=sharing
下面是重现此图的示例代码。这张图甚至可以变得更深。这只是一个简单的例子。请看图:
g.addV('SERVER').property(id, 'server1')
g.addV('SERVER').property(id, 'server2')
g.addV('ITEM').property(id, 'item1')
g.addV('ITEM').property(id, 'item2')
g.addV('ITEM').property(id, 'item3')
g.addV('ITEM').property(id, 'item4')
g.addV('USER').property(id, 'user1')
g.V('item1').addE('STORED IN').to(g.V('server1'))
g.V('item2').addE('STORED IN').to(g.V('server2'))
g.V('item2').addE('RELATED TO').to(g.V('item1'))
g.V('item3').addE('DERIVED FROM').to(g.V('item2') )
g.V('item3').addE('CREATED BY').to(g.V('user1'))
如果可能,结果应采用以下形式:
[
[
{
"V1": {},
"E": {},
"V2": {}
}
]
]
我们有一个带有端点的 API,它允许开放式 gremlin 查询。我们在客户端应用程序中调用此端点来获取可视化呈现的数据。我编写了一个查询,它只提供项目之间的一跳,但不遍历整个图形数据库。
g.V('${id}').as('V1').bothE().dedup().as('E')
.otherV().hasLabel(within('USER','ITEM')).as('V2').path().limit(500).select('V1', 'E', 'V2').fold()
如果可能的话,如果我能得到一个单独的查询来获取这个数据集,我将不胜感激。如果提供的顶点 id 的顶点没有连接到任何东西,我想检索它并在 UI 上单独呈现它。
解决方案
如果我正确理解了所有规则,那么以下查询应该会产生所需的结果:
g.V('${id}').aggregate('v1').
repeat(__.as('V1').bothE().dedup().as('E').otherV().hasLabel('USER','ITEM').as('V2').
aggregate('x').by(select('V1', 'E', 'V2'))).
until(hasLabel('USER')).
as('V1').bothE().dedup().as('E').otherV().hasLabel('ITEM').as('V2').
aggregate('x').
by(select('V1', 'E', 'V2')).
cap('v1','x','v1').
coalesce(select('x').unfold(),
select('v1').unfold().project('V1'))
在您的示例图上执行它会产生:
gremlin> g.V('server1').aggregate('v1').
......1> repeat(__.as('V1').bothE().dedup().as('E').otherV().hasLabel('USER','ITEM').as('V2').
......2> aggregate('x').by(select('V1', 'E', 'V2'))).
......3> until(hasLabel('USER')).
......4> as('V1').bothE().dedup().as('E').otherV().hasLabel('ITEM').as('V2').
......5> aggregate('x').
......6> by(select('V1', 'E', 'V2')).
......7> cap('v1','x','v1').
......8> coalesce(select('x').unfold(),
......9> select('v1').unfold().project('V1'))
==>[V1:v[server1],E:e[0][item1-STORED IN->server1],V2:v[item1]]
==>[V1:v[item1],E:e[2][item2-RELATED TO->item1],V2:v[item2]]
==>[V1:v[item2],E:e[3][item3-DERIVED FROM->item2],V2:v[item3]]
==>[V1:v[item3],E:e[4][item3-CREATED BY->user1],V2:v[user1]]
==>[V1:v[user1],E:e[4][item3-CREATED BY->user1],V2:v[item3]]
推荐阅读
- c - 我们如何使用 glade 和 C 创建一个简单的 GUI 应用程序?
- python - 为什么我不能从同级文件夹导入?
- tfs - 为什么 TFS Build Get Sources 返回错误 255?
- automation - 如果我使用 Cypress 和 appium,我需要 2 个自动化框架而不是 1 个带有 webdriver/appium 的框架。1 个框架更可取吗?
- javascript - 使用模板标签时密码字段中缺少眼睛图标
- node.js - 使用 AWS Lambda 函数连接到 Kubernetes
- sql - 在 oracle sql 中创建用户和密码
- java - Android:活动全屏透明操作栏不起作用?
- android - Android Studio 4.1+ 模拟器侧边栏?
- rest - ModuleNotFoundError:在 python 任何地方都没有名为“gspread”的模块