You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gremlin合并顶点时如何将重名属性值存为列表并保留所有出入边

问题说明

我需要合并顶点,同时保留其入边、出边以及全部属性。我参考了相关技术方案,它几乎完全符合我的预期,但当两个待合并顶点存在同名属性时,最终生成的合并顶点仅会保留其中一个属性值。我希望能将同名的多个属性值存储为列表,与为已存在对应属性的顶点添加属性时的默认行为一致。

示例场景:

g.V().has("author","book_id", 987).fold().
              coalesce(unfold(),
                       addV("author").property("book_id", 987))

g.V().hasLabel("author").has("book_id",987).property("author_id",123)


g.V().has("author","book_id", 654).fold().
              coalesce(unfold(),
                       addV("author").property("book_id", 654))

g.V().hasLabel("author").has("book_id",654).property("author_id",123)

执行以上4条查询后,会得到2个author_id=123的顶点。我使用如下查询合并这两个顶点:

g.V().has("author", "author_id", 123).fold().filter(count(local). is (gt(1))).unfold().
sideEffect(properties().group("p").by(key).by(value())).
sideEffect(outE().group("o").by(label).by(project("p", "iv").by(valueMap()).by(inV()).fold())).
sideEffect(inE().group("i").by(label).by(project("p", "ov").by(valueMap()).by(outV()).fold())).
sideEffect(drop()).
cap("p", "o", "i").as("poi").
addV("author").as("a").
sideEffect(
    select("poi").select("p").unfold().as("kv").
    select("a").property(select("kv").select(keys), select("kv").select(values))).
sideEffect(
    select("poi").select("o").unfold().as("x").select(values).
    unfold().addE(select("x").select(keys)).
from(select("a")).to(select("iv"))).
sideEffect(
    select("poi").select("i").unfold().as("x").select(values).
    unfold().addE(select("x").select(keys)).
from(select("ov")).to(select("a"))).iterate()   

执行后确实得到了预期的单个顶点,但查询其valueMap可知,book_id属性仅保留了一个值:

{'book_id': [654], 'author_id': [123]}

我要如何操作才能保留两个book_id的值,得到如下结果:

{'book_id': [654,987], 'author_id': [123]}

解决方案

问题根源是原查询的属性分组阶段仅保留了每个属性键的单个值,只需修改两处逻辑即可实现需求:

修正后的完整合并查询

g.V().has("author", "author_id", 123).fold().filter(count(local).is(gt(1))).unfold().
sideEffect(properties().group("p").by(key).by(value().fold())).
sideEffect(outE().group("o").by(label).by(project("p", "iv").by(valueMap()).by(inV()).fold())).
sideEffect(inE().group("i").by(label).by(project("p", "ov").by(valueMap()).by(outV()).fold())).
sideEffect(drop()).
cap("p", "o", "i").as("poi").
addV("author").as("a").
sideEffect(
    select("poi").select("p").unfold().as("kv").
    select("kv").select(values).unfold().as("v").
    select("a").property(select("kv").select(keys), select("v"))).
sideEffect(
    select("poi").select("o").unfold().as("x").select(values).
    unfold().addE(select("x").select(keys)).
from(select("a")).to(select("iv"))).
sideEffect(
    select("poi").select("i").unfold().as("x").select(values).
    unfold().addE(select("x").select(keys)).
from(select("ov")).to(select("a"))).iterate()

关键修改说明

  1. 将原查询中sideEffect(properties().group("p").by(key).by(value()))里的.by(value())替换为.by(value().fold()):这一步会把所有待合并顶点的同名属性值收拢为列表,避免仅保留最后一个值。
  2. 调整属性写入逻辑:原逻辑直接把收拢后的列表作为单个值传入property(),修改后先把列表展开为单个值逐个写入,和Gremlin给顶点追加属性的默认行为一致,同名属性会自动存储为列表格式。

执行修改后的查询后,再查询新顶点的valueMap即可得到预期结果。


内容的提问来源于stack exchange,提问作者Amitay Dror

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 14:06:02