如何优化Gremlin查询以输出指定结构的配方层级JSON?
问题:Gremlin查询生成配方层级JSON格式优化
我是Gremlin新手,若有表述不当之处敬请谅解!我拥有一个结构较为简单的配方与食材层级,希望编写Gremlin查询以输出如下格式的JSON:
{ "id": "sandwich-a", "name": "Sandwich A", "composedOf": [ { "id": "tomato", "name": "Tomato", "weight": 40, "composedOf": [] }, { "id": "sauce-a", "name": "Sauce A", "weight": 2.8, "composedOf": [ { "id": "salt", "name": "Salt", "weight": null, "composedOf": [] }, { "id": "pepper", "name": "Pepper", "weight": null, "composedOf": [] } ] }, { "id": "sauce-b", "name": "Sauce B", "weight": null, "composedOf": [ { "id": "water", "name": "Water", "weight": null, "composedOf": [] }, { "id": "lemon-juice", "name": "Lemon Juice", "weight": null, "composedOf": [] } ] } ] }
其中,id和name是顶点的属性;weight是边的属性,可能不存在;composedOf是通过标签为composed-of的边连接的顶点集合。
我目前编写的查询如下:
g.V() .has("id", "new-york-ciabatta") .project("id", "name", "composedOf") .by("id") .by("name") .by( repeat( out("composed-of") .outE().as('e') .inV().as('v') .simplePath() ) .emit() .tree())
该查询可正常运行,但会返回大量冗余数据,请问如何修改以输出上述指定格式的JSON?
解决方案
你需要用递归嵌套的project结构构建目标JSON,同时处理weight属性缺失的情况,保证叶子节点的composedOf为空数组。以下是优化后的查询:
g.V().has("id", "new-york-ciabatta"). project("id", "name", "composedOf"). by("id"). by("name"). by(outE("composed-of"). project("id", "name", "weight", "composedOf"). by(inV().values("id")). by(inV().values("name")). by(coalesce(values("weight"), constant(null))). by(inV(). project("id", "name", "composedOf"). by("id"). by("name"). by(outE("composed-of"). project("id", "name", "weight", "composedOf"). by(inV().values("id")). by(inV().values("name")). by(coalesce(values("weight"), constant(null))). by(inV().fold()). fold()). fold()). fold())
关键说明:
- 匹配层级结构:通过多层
project对应JSON的嵌套层级,每个子节点复用类似结构,确保composedOf的嵌套关系正确。 - 处理
weight属性:用coalesce(values("weight"), constant(null))实现“有属性则返回值,无则返回null”的逻辑。 - 空数组兜底:对无后续子节点的顶点,用
fold()将空的边集合转为空数组,保证composedOf始终是数组类型。 - 消除冗余:相比
tree()返回的全路径数据,这种方式仅保留当前节点的直接子节点,逐层构建结构,不会产生冗余内容。
如果你的配方层级深度不固定,可以用repeat()实现通用递归,无需手动嵌套多层project:
g.V().has("id", "new-york-ciabatta"). repeat( project("id", "name", "weight", "composedOf"). by(values("id")). by(values("name")). by(coalesce(__.inE("composed-of").values("weight"), constant(null))). by(outE("composed-of").inV().fold()) ).emit(). tree(). unfold().select(values).unfold()
手动嵌套适合层级固定的简单结构,repeat方式则适配深度不确定的场景。
内容的提问来源于stack exchange,提问作者zXynK
相关产品推荐
相关产品推荐

