首页 > 解决方案 > 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))

标签: javascriptgremlinamazon-neptune

解决方案


我不确定您要返回的数据是什么,但我收集到您正在寻找回答“此用户有权访问哪些对象以及权限是什么?”的问题。

如果是这种情况,那么从用户顶点开始遍历的最佳位置,然后您可以从中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不需要,那么您可以从遍历中删除它。


推荐阅读