Gremlin遍历树形结构获取直接父子节点对的性能优化方案
树形结构父子边聚合查询优化方案
需求说明
- 遍历树形结构,仅聚合父节点及其直接子节点,输出
[{父节点ID, 子节点ID}, ...]格式的列表,输出顺序无要求 - 参考示例预期输出:
[{0,1}, {0,2}, {1,8}, {1,6}, {2,7},{2,9}, {8,16},{8,14},{8,15},{7,17}] - 约束条件:
- 排除同节点自环边
- 图结构无反向循环回路,不存在子顶点指向父顶点的情况
- 所有顶点标签为city,所有边标签为highway
- 数据集约5000个顶点,任意两个顶点之间最多仅存在一条边
现有问题
当前使用的查询会触发超时:
g.V().hasLabel("city").toList().map(x->x.id()+x.edges(Direction.OUT,"highway").collect(Collectors.toList())
性能问题原因
原写法属于典型的N+1查询:先全量拉取所有顶点到客户端,再逐顶点单独发起出边查询请求,几千次网络往返开销直接导致执行超时。
优化方案
直接在服务端完成边的遍历、过滤和格式转换,仅发起一次请求即可拿到结果,优化后查询如下:
g.E().hasLabel("highway") // 过滤自环边 .where(outV().id().is(not(inV().id()))) // 输出父节点(边起点)和子节点(边终点)ID对 .project("parent", "child") .by(outV().id()) .by(inV().id()) .toList()
如果需要适配无key的二元组输出格式,可将project步骤替换为对应序列化逻辑,比如直接输出[outV().id(), inV().id()]的数组格式即可。
内容的提问来源于stack exchange,提问作者Baz1nga
相关产品推荐
相关产品推荐

