Gremlin查询Neptune数据库获取两节点路径并转d3适配JSON格式
问题解答
你可以使用GraphSONWriter实现该需求,但仅靠GraphSONWriter的默认输出无法直接生成符合d3.js要求的结构,需要先对Gremlin查询返回的路径结果做结构化处理,再做序列化输出,具体实现逻辑如下:
1. 先完成节点A到节点B的全路径查询
首先写出适配Neptune的Gremlin Python查询语句,查询所有无环的简单路径,同时提前拉取需要的节点、边属性:
from gremlin_python.process.anonymous_traversal import traversal from gremlin_python.process.graph_traversal import __ from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection # 连接Neptune实例 g = traversal().with_remote(DriverRemoteConnection('wss://<你的Neptune端点>:8182/gremlin', 'g')) # 假设节点A的name属性为"A",节点B的name属性为"B",限制最大路径长度为10避免超长路径占用资源 path_result = g.V().has('name', 'A') \ .repeat(__.bothE().otherV().simplePath()) \ .until(__.has('name', 'B')) \ .path() \ .by(__.valueMap('id', 'name', 'color').by(__.unfold())) \ .by(__.valueMap('source', 'target', 'color').by(__.unfold())) \ .to_list()
2. 路径结果转换为d3适配结构
这一步需要自行做节点去重、边聚合,比自定义GraphSON序列化规则更简单高效:
node_map = dict() link_list = [] link_exist = set() for path in path_result: elements = list(path) # 处理路径中的节点(路径内元素为节点、边交替排列) for i in range(0, len(elements), 2): node = elements[i] node_id = node['id'] if node_id not in node_map: node_map[node_id] = { "id": node_id, "name": node['name'], "color": node['color'] } # 处理路径中的边,同时做边去重 for i in range(1, len(elements), 2): edge = elements[i] source_id = edge['source'] target_id = edge['target'] link_key = f"{source_id}_{target_id}_{edge['color']}" if link_key not in link_exist: link_exist.add(link_key) link_list.append({ "source": source_id, "target": target_id, "color": edge['color'] }) # 最终生成d3可直接加载的结构 d3_graph = { "nodes": list(node_map.values()), "links": link_list }
3. 序列化输出JSON
如果要使用GraphSONWriter序列化,配置方式如下:
from gremlin_python.structure.io import graphson writer = graphson.GraphSONWriter() d3_json = writer.writeObject(d3_graph)
如果不需要处理Gremlin特殊类型,直接用Python内置json模块更便捷:
import json d3_json = json.dumps(d3_graph, indent=2)
输出的JSON可直接传入d3.js的力导向图等组件加载使用。
内容的提问来源于stack exchange,提问作者question1234
相关产品推荐
相关产品推荐

