如何将gremlinpython 3.6.1的elementMap路径查询结果转为JSON
解决GremlinPython路径查询结果转标准JSON的问题
问题背景
使用gremlinpython 3.6.1执行包含elementMap()的路径查询后,尝试用graphsonV3d0.GraphSONWriter转换结果,输出带有Gremlin特定类型标识(如@type、@value),不符合纯标准JSON的预期,需要调整转换方式。
示例场景
1. 示例图构建语句
from gremlin_python.process.anonymous_traversal import traversal from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection from gremlin_python.process.traversal import __ g = traversal().withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','g')) # 创建示例图 g.addV('person').property('name', 'Alice').property('age', 30).as_('a'). addV('person').property('name', 'Bob').property('age', 25).as_('b'). addE('knows').from_('a').to('b').property('since', 2020).iterate()
2. 查询语句
result = g.V().has('name', 'Alice').outE('knows').inV().path().by(__.elementMap()).toList()
3. 当前不符合预期的输出
[ { "@type": "g:Path", "@value": [ { "@type": "g:Map", "@value": [ "id", {"@type": "g:Int32", "@value": 1}, "label", "person", "name", "Alice", "age", {"@type": "g:Int32", "@value": 30} ] }, { "@type": "g:Map", "@value": [ "id", {"@type": "g:Int64", "@value": 3}, "label", "knows", "since", {"@type": "g:Int32", "@value": 2020}, "IN", {"@type": "g:Vertex", "@value": {"@type": "g:Int32", "@value": 2}}, "OUT", {"@type": "g:Vertex", "@value": {"@type": "g:Int32", "@value": 1}} ] }, { "@type": "g:Map", "@value": [ "id", {"@type": "g:Int32", "@value": 2}, "label", "person", "name", "Bob", "age", {"@type": "g:Int32", "@value": 25} ] } ] } ]
4. 期望的标准JSON格式
[ { "path": [ { "id": 1, "label": "person", "name": "Alice", "age": 30 }, { "id": 3, "label": "knows", "since": 2020, "IN": 2, "OUT": 1 }, { "id": 2, "label": "person", "name": "Bob", "age": 25 } ] } ]
解决方案
方法1:手动遍历结果转换(最灵活)
直接解析Gremlin返回的对象,提取字段并转换为原生Python类型,再用json.dumps()序列化:
import json def convert_path(path_obj): path_elements = [] for elem in path_obj: converted = {} for k, v in elem.items(): # 处理基础类型 if isinstance(v, (int, str, bool, float)): converted[k] = v # 处理指向顶点的属性(如IN/OUT),提取ID elif hasattr(v, 'id'): converted[k] = v.id path_elements.append(converted) return {"path": path_elements} # 转换所有结果 converted_results = [convert_path(path) for path in result] # 输出标准JSON print(json.dumps(converted_results, indent=2))
方法2:优化Gremlin查询(性能最优)
在查询阶段直接构造接近目标结构的输出,减少客户端转换工作:
# 修改查询,通过project()直接定义输出结构 result = g.V().has('name', 'Alice').outE('knows').inV().path().by( __.project('id','label','name','age').by(__.id()).by(__.label()).by('name').by('age') ).by( __.project('id','label','since','IN','OUT').by(__.id()).by(__.label()).by('since').by(__.inV().id()).by(__.outV().id()) ).toList() # 直接序列化即可得到标准JSON print(json.dumps(result, indent=2))
方法3:自定义GraphSON序列化配置
如果依赖GraphSONWriter,可以通过自定义Mapper去除类型标识:
from gremlin_python.structure.io.graphsonV3d0 import GraphSONWriter, GraphSONMapper import json class CustomGraphSONMapper(GraphSONMapper): def to_dict(self, obj): if isinstance(obj, dict) and '@type' in obj and '@value' in obj: return self.to_dict(obj['@value']) elif isinstance(obj, list): return [self.to_dict(item) for item in obj] elif isinstance(obj, dict): return {k: self.to_dict(v) for k, v in obj.items()} else: return obj # 使用自定义Mapper序列化 writer = GraphSONWriter(mapper=CustomGraphSONMapper()) raw_json = writer.writeObject(result) # 解析后重新格式化 final_json = json.loads(raw_json) print(json.dumps(final_json, indent=2))
方案对比
- 方法1:适配所有查询场景,完全控制输出结构,适合复杂结果转换;
- 方法2:将转换逻辑放在Gremlin服务器端,减少客户端计算开销,性能更优;
- 方法3:保留GraphSON工具链,适合需要兼容部分Gremlin特性的场景,但需处理类型转换细节。
内容的提问来源于stack exchange,提问作者Anil_M
相关产品推荐
相关产品推荐

