首页 > 解决方案 > 如何在 gremlin 查询中合并来自不同对象的值?

问题描述

我有一个查询以下列格式返回输出,

{
    "Key": [
      "Value1",
      "Value2"
    ],
    "Count": [
      {
        "Count1": 28,
        "Count2": 28
      },
      {
        "Count3": 16,
        "Count4": 16
      }
    ]
  }

我想以以下格式显示它

[
  {
     "Key" : "Value1",
     "Count1": 28,
     "Count2": 28
  },
  {
     "Key" : "Value2",
     "Count3": 16,
     "Count4": 16
  }
]

可能吗?

产生类似输出的 gremlin


g.V().
has('organizationId', 'b121672e-8049-40cc-9f28-c62dff4cc2d9').
hasLabel('employee').

group(). 
by('officeId').
by(project('Id', 'Status').
    by(choose(has('officeId'), constant('Total'), constant(''))).
    by(coalesce(out('hasStatus').
                or(
                        has('release', is(false)),                          
                        has('autoRelease', is(true)).
                        has('release', is(true)).
                        has('endDate', gte(637250976000000000))
                 ), values('status'), constant('Green'))).
    select(values).
    unfold().
    groupCount()).

    project('Id', 'Count').
    by(select(keys)).
    by(select(values))

我拥有的数据是一个员工顶点和一个健康状态顶点,员工和健康状态之间有一个hasStatus边缘

员工顶点中的属性: id、organizations、officeId、Name、createdOn

healthStatus 顶点中的属性: id、status、startDate、endDate、release、autoRelease、createdOn

样本数据

 g.addV('employee').
       property('id',1).
       property('organizationId',1).
       property('officeId',1).
       property('name','A').
       property('createdOn', 637263231140000000).as('1').
    addV('employee').
       property('id',2).
       property('organizationId',1).
       property('officeId',2).
       property('name','B').
       property('createdOn', 637263231140000000).as('2').
   addV('employee').
       property('id',5).
       property('organizationId',1).
       property('officeId',3).
       property('name','C').
       property('createdOn', 637263231140000000).as('5').
    addV('healthStatus').
       property('id',3).
       property('status','Red').
       property('startDate',637262367140000000).
       property('endDate',637264095140000000).
       property('release',false).
       property('createdOn',637262367140000000)as('3').
    addV('healthStatus').
       property('id',4).
       property('status','Yellow').
       property('startDate',637262367140000000).
       property('endDate',637264095140000000).
       property('release',false).
       property('createdOn',637262367140000000)as('4').
    addE('hasStatus').from('1').to('3').
    addE('hasStatus').from('4').to('4')

输出:

[
  {
    "Id" : [
        1,
        2,
        3
      ]
  },
  {
    "Count": [
      {
         "Red" : 1
      },
      {
         "Yellow" : 1
      },
      {
         "Green" : 1
      }
    ]  
  }

预期产出

[
  {
     "Id" : 1,
     "Red" : 1
  },
  {
     "Id" : 2,
     "Yellow" : 1
  },
  {
     "Id" : 3,
     "Green" : 1
  }
]

注意:投影中的这个 ID 是来自员工顶点的 officeId

标签: gremlintinkerpopgremlin-serverazure-cosmosdb-gremlinapi

解决方案


我想我已经抓住了你想要的东西。您的示例数据脚本中有一些错误,我想要一些额外的数据来确保计数有意义,所以我添加了一些:

 g = TinkerGraph.open().traversal()
 g.addV('employee').
       property('id',1).
       property('organizationId',1).
       property('officeId',1).
       property('name','A').
       property('createdOn', 637263231140000000).as('1').
    addV('employee').
       property('id',2).
       property('organizationId',1).
       property('officeId',2).
       property('name','B').
       property('createdOn', 637263231140000000).as('2').
   addV('employee').
       property('id',5).
       property('organizationId',1).
       property('officeId',3).
       property('name','C').
       property('createdOn', 637263231140000000).as('5').
   addV('employee').
       property('id',6).
       property('organizationId',1).
       property('officeId',3).
       property('name','D').
       property('createdOn', 637263231140000000).as('6').
    addV('healthStatus').
       property('id',3).
       property('status','Red').
       property('startDate',637262367140000000).
       property('endDate',637264095140000000).
       property('release',false).
       property('createdOn',637262367140000000).as('3').
    addV('healthStatus').
       property('id',4).
       property('status','Yellow').
       property('startDate',637262367140000000).
       property('endDate',637264095140000000).
       property('release',false).
       property('createdOn',637262367140000000).as('4').
    addE('hasStatus').from('1').to('3').
    addE('hasStatus').from('2').to('4').
    addE('hasStatus').from('6').to('4')

我已经重写了你的遍历,以提供一种不同的方法,我认为它可以提供你期望的数据,但是形式略有不同:

gremlin> g.V().has('employee','organizationId', 1).
......1>   project('Id', 'Status').
......2>     by('officeId').
......3>     by(coalesce(out('hasStatus').
......4>                 or(has('release', false),                          
......5>                    has('autoRelease', true).has('release', true).has('endDate', gte(637250976000000000))). 
......6>                 values('status'), 
......7>                 constant('Green'))).
......8>   group().
......9>     by(select('Id')).
.....10>     by(groupCount().
.....11>          by('Status'))
==>[1:[Red:1],2:[Yellow:1],3:[Yellow:1,Green:1]]

我更喜欢这种形式,但也许您需要您询问的原始格式,在这种情况下,您需要对集合进行另一轮操作:

gremlin> g.V().has('employee','organizationId', 1).
......1>   project('Id', 'Status').
......2>     by('officeId').
......3>     by(coalesce(out('hasStatus').
......4>                 or(has('release', false),                          
......5>                    has('autoRelease', true).has('release', true).has('endDate', gte(637250976000000000))). 
......6>                 values('status'), 
......7>                 constant('Green'))).
......8>   group().
......9>     by(select('Id')).
.....10>     by(groupCount().
.....11>          by('Status')).
.....12>   unfold().
.....13>   map(union(project('Id').by(select(keys)),
.....14>             select(values)).
.....15>       unfold().
.....16>       group().by(keys).by(select(values)))
==>[Red:1,Id:1]
==>[Yellow:1,Id:2]
==>[Yellow:1,Id:3,Green:1]

推荐阅读