javascript - Gremlin (Neptune) 有些复杂的查询不显示边缘属性
问题描述
我的数据库(AWS Neptune)中有一组数据,我使用 Gremlin(NodeJS)对其进行查询。
数据看起来像这样,我有一个看起来像这样的查询:
g.V().hasLabel('group').inE('belongs_to')
.outV().has('user_id', user_id).outE()
.otherV().inE().hasLabel('shared_with')
.outV().has('type', type).aggregate('object_id').fold()
.V().hasLabel('user').has('user_id', user_id).inE().hasLabel('shared_with')
.outV().has('type', type).aggregate('object_id').cap('object_id')
.unfold().dedup().valueMap().toList();
我最终得到的(这是正确的)是一个对象列表以及它们与谁共享,“谁”可以是用户或组。所以这是一个好的开始(我花了一段时间才得到它,我从 StackOverflow 中抓住了主要思想),但我没有得到边缘的属性。
最初,我有两个单独的查询,一个用于与组共享的对象,另一个用于与用户共享的对象。这很好,但显然需要更多时间,我不得不重新调整我得到的两个列表。
我试图修改我的查询,将 as('x') 放在我需要的边缘和顶点后面,但随后选择根本没有返回任何内容。如果没有 select(),as() 将被忽略,我会得到与以前相同的数据。
我最初尝试使用 .local(__.union()) 但这也不起作用。我上周开始使用 Gremlin/Neptune,虽然我取得了不错的进展,但我只能使用一些简单的查询 :(
更新:
以下是我创建组的方式:
let group = await g.addV('group')
.property('group_id', group_id)
.property('name', name)
.property('type', groupType)
.property('owner', owner)
.next();
//group_id and owner are UUID.
如何将用户添加到组:
t = await g.addV('user')
.property('user_id', user.id)
.property('name', user.name)
.next();
t = await g.V()
.has('user', 'user_id', user.id) // Find the user
.addE('belongs_to') // Add a new edge
.to(g.V().has('group', 'group_id', group_id))
// user.id is a UUID
对象创建:
let obj = await g.addV('object')
.property('object_id', object_id)
.property('ref', ref)
.property('type', type)
.property('owner', owner)
.property('creation_time', d.getTime().toString())
.next();
与用户或组共享:
t = await g.V().has('object','object_id', object_id).has('owner', owner)
.addE('shared_with') // Add a new edge
.property('read', canRead)
.property('edit', canEdit)
.property('share', canShare)
.to(g.V().has('user', 'user_id', id)) // Find the user to link to
.next();
// For group: .to(g.V().has('group', 'group_id', id))
解决方案
我不确定您要返回的数据是什么,但我收集到您正在寻找回答“此用户有权访问哪些对象以及权限是什么?”的问题。
如果是这种情况,那么从用户顶点开始遍历的最佳位置,然后您可以从中union()
与组共享的对象到直接共享给用户的对象。最后,您可以project()
从 shared_with 边缘获取对象的值以及权限的边缘属性。
g.V().has('User', 'user_id', 'A').
union(
out('belongs_to').inE('shared_with'),
inE('shared_with')
).project('object', 'permission').
by(outV().valueMap().with(WithOptions.tokens)).
by(valueMap().with(WithOptions.tokens))
将with(WithOptions.tokens)
包括元数据,例如,id
如果label
不需要,那么您可以从遍历中删除它。
推荐阅读
- postgresql - 舍入值 Postgresql
- java - 如何在片段中使用 EventBus?
- git - 使用 git 删除已删除的文件夹
- wso2esb - WSO2 esb 在什么情况下端点可以处于关闭状态
- php - TCPDF:getimagesize():SSL 操作失败,代码 1 错误:1416F086:SSL 例程:tls_process_server_certificate:证书验证失败
- git - 当合并来自源分支的某些文件时,目标分支中没有显示?
- django - 在 git 分支之间维护数据库表字段的最佳方法是什么?
- javascript - 在 JavaScript 中是否有一种简单的方法来获取 url 指向的字符串?
- mysql - 如何根据mysql中的两列连接表?
- php - phpmailer电子邮件发送不起作用