JanusGraph propertyMap()序列化问题:如何获取纯净键值对?
问题解决:JanusGraph返回纯净键值对适配方案
核心问题
搭建对接Neo4j/JanusGraph的Java应用,要求接口返回Collection<Map<String, Object>>格式的纯净键值对(如{"name": "mario"})。Neo4j Spring客户端默认返回符合要求的结果,但JanusGraph使用propertyMap()时返回带冗余标识的结果(如{"name": "vp[name->mario]"}),尝试GraphSON序列化器及g.V().hasLabel("Person").propertyMap().by(unfold()).toList()遍历语句均失败,需找到适配方案。
当前配置
连接代码
TypeSerializerRegistry typeSerializerRegistry = TypeSerializerRegistry.build() .addRegistry(JanusGraphIoRegistry.instance()) .create(); Cluster cluster = Cluster.build(host) .port(Integer.parseInt(port)) .serializer(new GraphBinaryMessageSerializerV1(typeSerializerRegistry)) .enableSsl(false) .create(); Object driver = traversal().withRemote( DriverRemoteConnection.using(cluster, "g") );
POM依赖
<dependency> <groupId>org.janusgraph</groupId> <artifactId>janusgraph-core</artifactId> <version>0.6.3</version> </dependency> <dependency> <groupId>org.apache.tinkerpop</groupId> <artifactId>gremlin-driver</artifactId> <version>3.5.5</version> </dependency>
解决方案
方案1:修正Gremlin遍历语句(推荐)
propertyMap()返回的是Property对象实例,而非纯属性值,这是导致冗余标识的根本原因。改用valueMap()或project()直接获取纯属性值,无需依赖序列化器处理:
使用valueMap()(返回指定/所有属性的纯值)
// 获取Person节点的所有属性,自动展开集合类型属性为单个值 List<Map<String, Object>> result = g.V().hasLabel("Person") .valueMap() .by(unfold()) .toList();
使用project()(精确指定需要返回的属性)
如果只需部分属性,用project()更高效:
// 仅返回name和age属性的纯值 List<Map<String, Object>> result = g.V().hasLabel("Person") .project("name", "age") .by("name") .by("age") .toList();
方案2:配置适配的GraphSON序列化器
若坚持使用propertyMap(),需确保GraphSON序列化器能正确解析Property对象。之前失败的原因大概率是未配置JanusGraph的IoRegistry,导致序列化器无法识别JanusGraph的自定义类型。配置示例:
// 构建支持JanusGraph类型的GraphSON映射器 GraphSONMapper graphSONMapper = GraphSONMapper.build() .addRegistry(JanusGraphIoRegistry.instance()) .typeSerializerRegistry(TypeSerializerRegistry.build() .addRegistry(JanusGraphIoRegistry.instance()) .create()) .create(); // 配置Cluster使用GraphSON3序列化器 Cluster cluster = Cluster.build(host) .port(Integer.parseInt(port)) .serializer(new GraphSON3MessageSerializerV1(graphSONMapper)) .enableSsl(false) .create(); GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster, "g"));
配置后,propertyMap().by(unfold())返回的结果会被正确序列化为纯键值对,不再包含冗余标识。
内容的提问来源于stack exchange,提问作者quetzalCoatlus
相关产品推荐
相关产品推荐

