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

如何从图的Edge属性提取Substring并优化Gremlin查询

问题描述

需要从图中company-company类型边的ID字段提取子串生成shr_id,同时优化查询输出格式以匹配预期结果。

图结构初始化代码

g.addV('company').property(id,'SHRTST01').property('name','Alphabet').next()
g.addV('company').property(id,'SHRTST02').property('name','Google').next()
g.addV('company').property(id,'SHRTST03').property('name','Youtube').next()
g.addV('company').property(id,'SHRTST05').property('name','YoutubeKids').next()
g.addV('person').property(id,'SHRTST01_1900-01-01_1_1').property('bu_id', 'SHRTST01_1900-01-01_1_1').property('name', 'W Karl David Laxton').next()
g.addV('person').property(id,'SHRTST02_1900-01-01_1_1').property('bu_id', 'SHRTST02_1900-01-01_1_1').property('name', 'Steven H Strong').next()


g.addE('HAS_SHRHLDING_PC_TO').from(__.V('SHRTST01')).to(__.V('SHRTST01_1900-01-01_1_1')).property(id,'SHRTST01_HAS_SHRHLDING_PC_TO_SHRTST01_1900-01-01_1_1').property('perc_value', 30).next()
g.addE('HAS_VOTING_PC_TO').from(__.V('SHRTST01')).to(__.V('SHRTST01_1900-01-01_1_1')).property(id,'SHRTST01_HAS_VOTING_PC_TO_SHRTST01_1900-01-01_1_1').property('perc_value', 50).next()
g.addE('HAS_SHRHLDING_PC_TO').from(__.V('SHRTST01')).to(__.V('SHRTST02')).property(id,'SHRTST01_HAS_SHRHLDING_PC_TO_SHRTST02_2002-01-01_2_2').property('perc_value', 75).next()
g.addE('HAS_VOTING_PC_TO').from(__.V('SHRTST01')).to(__.V('SHRTST02')).property(id,'SHRTST01_HAS_VOTING_PC_TO_SHRTST02_2002-01-01_2_2').property('perc_value', 50).next()
g.addE('HAS_SHRHLDING_PC_TO').from(__.V('SHRTST02')).to(__.V('SHRTST02_1900-01-01_1_1')).property(id,'SHRTST02_HAS_SHRHLDING_PC_TO_SHRTST02_1900-01-01_1_1').property('perc_value', 25).next()
g.addE('HAS_VOTING_PC_TO').from(__.V('SHRTST02')).to(__.V('SHRTST02_1900-01-01_1_1')).property(id,'SHRTST02_HAS_VOTING_PC_TO_SHRTST02_1900-01-01_1_1').property('perc_value', 23).next()
g.addE('HAS_SHRHLDING_PC_TO').from(__.V('SHRTST02')).to(__.V('SHRTST03')).property(id,'SHRTST02_HAS_SHRHLDING_PC_TO_SHRTST03_2002-01-01_2_2').property('perc_value', 80).next()
g.addE('HAS_VOTING_PC_TO').from(__.V('SHRTST02')).to(__.V('SHRTST03')).property(id,'SHRTST03_HAS_VOTING_PC_TO_SHRTST02_2003-01-01_2_2').property('perc_value', 20).next()
g.addE('HAS_SHRHLDING_PC_TO').from(__.V('SHRTST03')).to(__.V('SHRTST05')).property(id,'SHRTST03_HAS_SHRHLDING_PC_TO_SHRTST05_2002-01-01_2_2').property('perc_value', 75).next()
g.addE('HAS_VOTING_PC_TO').from(__.V('SHRTST03')).to(__.V('SHRTST05')).property(id,'SHRTST03_HAS_VOTING_PC_TO_SHRTST05_2002-01-01_2_2').property('perc_value', 30).next()

当前查询语句

g.V('SHRTST01').as('crn')
 .repeat(
  outE('HAS_SHRHLDING_PC_TO').as('edge_field')
 .inV()
 .simplePath())
 .until(not(outE()))
 .emit()
 .hasLabel('company')
 .select('crn','edge_field')
 .project('crn', 'edge_field')
 .by(select(keys).select('crn'))
 .by(select(keys).select('edge_field'))

实际输出

{'crn': v[SHRTST01], 'edge_field': e[SHRTST01_HAS_SHRHLDING_PC_TO_SHRTST02_2002-01-01_2_2][SHRTST01-HAS_SHRHLDING_PC_TO->SHRTST02]}
{'crn': v[SHRTST01], 'edge_field': e[SHRTST02_HAS_SHRHLDING_PC_TO_SHRTST03_2002-01-01_2_2][SHRTST02-HAS_SHRHLDING_PC_TO->SHRTST03]}
{'crn': v[SHRTST01], 'edge_field': e[SHRTST03_HAS_SHRHLDING_PC_TO_SHRTST05_2002-01-01_2_2][SHRTST03-HAS_SHRHLDING_PC_TO->SHRTST05]}

预期输出

{'crn': [SHRTST01], 'edge_field': [SHRTST01_HAS_SHRHLDING_PC_TO_SHRTST02_2002-01-01_2_2], 'shr_id':[SHRTST02_2002-01-01_2_2]}
{'crn': [SHRTST01], 'edge_field': [SHRTST02_HAS_SHRHLDING_PC_TO_SHRTST03_2002-01-01_2_2], 'shr_id':[SHRTST03_2002-01-01_2_2]}
{'crn': [SHRTST01], 'edge_field': [SHRTST03_HAS_SHRHLDING_PC_TO_SHRTST05_2002-01-01_2_2], 'shr_id':[SHRTST05_2002-01-01_2_2]}

核心问题

  1. 如何从边ID中提取子串生成shr_id(shr_id是边ID中_SHRTST之后的部分,例如从SHRTST01_HAS_SHRHLDING_PC_TO_SHRTST02_2002-01-01_2_2提取SHRTST02_2002-01-01_2_2)
  2. 如何优化查询语句,将输出格式调整为预期的数组形式

解决方案

优化后的查询语句

g.V('SHRTST01').as('crn')
 .repeat(
  outE('HAS_SHRHLDING_PC_TO').as('edge_field')
 .inV()
 .simplePath())
 .until(not(outE()))
 .emit()
 .hasLabel('company')
 .project('crn', 'edge_field', 'shr_id')
 .by(select('crn').id().fold())
 .by(select('edge_field').id().fold())
 .by(select('edge_field').id().map { it.split('_SHRTST')[1] }.map { "SHRTST${it}" }.fold())

关键说明

  1. 提取shr_id:
    • 利用split('_SHRTST')将边ID分割为两部分,取索引1的部分,再拼接回SHRTST前缀,得到目标shr_id
    • 示例:SHRTST01_HAS_SHRHLDING_PC_TO_SHRTST02_2002-01-01_2_2 → split后得到['SHRTST01_HAS_SHRHLDING_PC_TO', '02_2002-01-01_2_2'] → 拼接后为SHRTST02_2002-01-01_2_2
  2. 输出数组格式:
    • 使用fold()将单个值包装为数组,匹配预期输出格式
    • 简化原查询中冗余的嵌套select操作,直接通过project结合id().fold()获取顶点/边的ID并转为数组
  3. 过滤company-company边:
    • 原查询中的hasLabel('company')已确保只保留指向company的边,符合需求场景

更优处理思路

  • 避免从ID中提取业务数据:建议创建边时直接将shr_id作为边属性存储,而非从ID解析。这能避免ID格式变更导致的解析失败,同时提升查询性能
  • 简化遍历逻辑:若仅需一级company-company关联,可去掉repeat和until,直接用outE('HAS_SHRHLDING_PC_TO').inV().hasLabel('company'),减少不必要的递归遍历
  • 索引优化:为company标签的顶点ID、HAS_SHRHLDING_PC_TO边标签创建索引,提升查询遍历效率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 00:33:14