GremlinNeptune有点复杂的查询不会显示边缘属性

问题描述

我的数据库(AWS Neptune)中有一组数据,并使用Gremlin(NodeJS)查询

enter image description here

数据看起来像这样,我有一个看起来像这样的查询

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();

我最终得到的结果(正确)是对象列表,以及与之共享的对象,“ whom”可以是用户或组。 因此,这是一个不错的开始(花了我一段时间,然后我从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',id))  // Find the user to link to
         .next();

// For group: .to(g.V().has('group',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@Bean public ProducerFactory<String,GeneralMessageDto> generalMessageProducerFactory() { Map<String,Object> configProps = new HashMap<>(); configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,bootstrapAddress); configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,StringSerializer.class); configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,JsonSerializer.class); configProps.put("sasl.mechanism","PLAIN"); configProps.put("sasl.jaas.config","org.apache.kafka.common.security.plain.PlainLoginModule required username='YOUR_KAFKA_CLUSTER_USERNAME' password='YOUR_KAFKA_CLUSTER_PASSWORD';"); configProps.put("security.protocol","SASL_SSL"); return new DefaultKafkaProducerFactory<>(configProps); } 之类的元数据,因此如果不需要,则可以从遍历中删除它。