Gremlin(Amazon Neptune)查询:获取与指定用户同购游戏的用户及公共游戏列表
核心需求与现存问题
- 运行环境:当前基于Amazon Neptune搭建简单图数据库,查询代码在AWS Jupyter Notebook中运行,后续计划迁移至
gremlin_python客户端环境,属于Gremlin入门用户 - 图初始化数据:共3个
person类型顶点(id为john/jim/pam)、3个game类型顶点(id为G1/G2/G3),顶点间通过bought类型边记录用户购买游戏的关系 - 待实现逻辑:给定任意目标用户,查询所有和目标存在共同购买游戏的其他用户,返回每个关联用户对应的共同游戏ID列表,结果按共同游戏数量降序排列
- 现有查询的不足:当前编写的脚本仅能返回每个关联用户与目标的共同游戏计数,无法展示具体的共同游戏ID,现有输出为
{v[jim]: 2}、{v[pam]: 1},期望输出格式为{v[jim]: ['G1', 'G2']}、{v[pam]: ['G1']}
问题根源
原有查询在执行group()聚合操作时,value映射分支使用了.count()作为遍历逻辑,直接统计符合条件的共同游戏数量,没有实际收集游戏ID内容,因此仅能得到计数值。
优化实现
直接调整group()聚合时的value分支遍历逻辑,将计数操作替换为收集共同游戏的ID列表,即可得到目标格式的返回结果:
g.V('john').as('target') // 替换为任意目标用户ID即可查询对应结果 .out('bought').aggregate('target_games') // 聚合目标用户购买的全量游戏集合 .in('bought').where(P.neq('target')).dedup() // 定位购买过目标关联游戏的其他用户,排除目标本身并去重 .group() .by() // 分组键为其他用户的顶点本身 .by( out("bought") .where(P.within("target_games")) // 筛选该用户同时和目标都购买过的游戏 .values('id') // 提取共同游戏的id属性 .fold() // 将收集到的ID聚合为列表 ) .unfold() // 将group返回的Map结构展开为独立的键值对条目 .order() .by(values, desc) // 按共同游戏数量(即列表长度)降序排序 .toList()
注意事项
- 排序逻辑无需额外调整:当
order().by()的排序值为列表类型时,会自动以列表长度作为排序依据,完全匹配按共同游戏数降序的要求 - 该脚本完全兼容
gremlin_python运行环境,后续迁移时无需调整核心语法 - 可以根据需要调整提取的内容,比如如果需要返回游戏顶点本身而非ID,只需去掉
.values('id')步骤即可
内容的提问来源于stack exchange,提问作者G_E
相关产品推荐
相关产品推荐

