You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Azure CosmosDB的Gremlin图查询:分组排序检索特定顶点

Gremlin + Azure CosmosDB 图查询问题

图结构定义

1. 添加object1类型顶点

g.addV('object1').property('id','1').addV('object1').property('id','2')

2. 添加object2类型顶点

g.addV('object2').property('id','1').property('date', '01-08-2023').property('type', 'ordinary').property('object1', '1')
.addV('object2').property('id', '2').property('date', '02-08-2023').property('type', 'special').property('object1', '1')
.addV('object2').property('id', '3').property('date', '31-07-2023').property('type', 'ordinary').property('object1', '1')

.addV('object2').property('id','4').property('date', '01-07-2023').property('type', 'ordinary').property('object1', '2')
.addV('object2').property('id','5').property('date', '02-07-2023').property('type', 'special').property('object1', '2')
.addV('object2').property('id','6').property('date', '30-06-2023').property('type', 'ordinary').property('object1', '2')

3. 添加object2与object1的关联边

g.V().hasLabel('object1').has('id', '1').addE('SCANNED').from(g.V().hasLabel('object2').has('id', '1'))
g.V().hasLabel('object1').has('id', '1').addE('SCANNED').from(g.V().hasLabel('object2').has('id', '2'))
g.V().hasLabel('object1').has('id', '1').addE('SCANNED').from(g.V().hasLabel('object2').has('id', '3'))

g.V().hasLabel('object1').has('id', '2').addE('SCANNED').from(g.V().hasLabel('object2').has('id', '4'))
g.V().hasLabel('object1').has('id', '2').addE('SCANNED').from(g.V().hasLabel('object2').has('id', '5'))
g.V().hasLabel('object1').has('id', '2').addE('SCANNED').from(g.V().hasLabel('object2').has('id', '6'))

关联关系说明

object2顶点[id:1,2,3] —SCANNED—> object1[id:1]
object2顶点[id:4,5,6] —SCANNED—> object1[id:2]

查询需求

针对每个object1,完成以下操作:

  1. 找出类型为ordinary的最新object2顶点;
  2. 找出类型为special且时间晚于步骤1中object2的最新顶点;
  3. 收集步骤1和2中的object2顶点,用于后续遍历。

预期输出:[object2 id:1, object2 id:2, object2 id:4, object2 id:5]

已尝试的分组查询

已实现按object1分组的查询:

g.V().hasLabel("object1").in("SCANNED").group().by("object1")

分组结果:

[
{
1: [
      { 'id' : '1', 'date': '01-08-2023', 'type': 'ordinary', "object1": '1'},
      { 'id' : '2', 'date': '02-08-2023', 'type': 'special', "object1": '1'},
      { 'id' : '3', 'date': '31-07-2023', 'type': 'ordinary', "object1": '1'}
],
2:[
     { 'id' : '4', 'date': '01-07-2023', 'type': 'ordinary', "object1": '2'},
     { 'id' : '5', 'date': '02-07-2023', 'type': 'special', "object1": '2'},
     { 'id' : '6', 'date': '30-06-2023', 'type': 'ordinary', "object1": '2'}
]
}
]

待解决问题及解决方案

1. 如何对object2排序,获取类型为ordinary的最新顶点?

通过类型过滤+日期降序排序+取第一条的方式实现:

// 单个object1查询示例
g.V().hasLabel('object1').has('id','1').in('SCANNED').has('type','ordinary').order().by('date', desc).limit(1)

// 批量按object1分组获取
g.V().hasLabel('object1').group().by('id').by(
    in('SCANNED').has('type','ordinary').order().by('date', desc).limit(1)
)

2. 如何获取类型为special且时间晚于步骤1中顶点的最新object2?

先获取步骤1的最新ordinary顶点日期,再过滤符合条件的special顶点并取最新:

// 单个object1查询示例
g.V().hasLabel('object1').has('id','1').as('o1').
  in('SCANNED').has('type','ordinary').order().by('date', desc).limit(1).as('latestOrdinary').
  select('o1').in('SCANNED').has('type','special').
  where('date', gt(select('latestOrdinary').values('date'))).
  order().by('date', desc).limit(1)

// 批量按object1分组处理
g.V().hasLabel('object1').group().by('id').by(
  union(
    // 步骤1:获取最新ordinary顶点
    in('SCANNED').has('type','ordinary').order().by('date', desc).limit(1),
    // 步骤2:获取符合条件的special顶点
    in('SCANNED').has('type','ordinary').order().by('date', desc).limit(1).as('lo').
      select('$$').in('SCANNED').has('type','special').where('date', gt(select('lo').values('date'))).
      order().by('date', desc).limit(1)
  ).fold()
)

3. 如何检索这些顶点以用于后续遍历?

用flatMap+union收集所有符合条件的顶点,直接用于后续操作:

// 收集所有目标顶点,返回的集合可直接用于后续遍历
g.V().hasLabel('object1').flatMap(
  union(
    in('SCANNED').has('type','ordinary').order().by('date', desc).limit(1),
    in('SCANNED').has('type','ordinary').order().by('date', desc).limit(1).as('lo').
      select('$$').in('SCANNED').has('type','special').where('date', gt(select('lo').values('date'))).
      order().by('date', desc).limit(1)
  )
).dedup()

内容的提问来源于stack exchange,提问作者ajj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:04:56