使用gremlin添加边缘(如果不存在)

时间:2018-09-21 15:54:55

标签: graph gremlin

我正在使用Azure宇宙图数据库。

有人知道只有在不存在两个顶点之间才可以添加边的方法吗(使用gremlin图查询)?

我可以在添加顶点时做到这一点,但不能添加边。我从here处获取了代码来完成此操作:

g.Inject(0).coalesce(__.V().has('id', 'idOne'), addV('User').property('id', 'idOne'))

谢谢!

3 个答案:

答案 0 :(得分:8)

可以处理边缘。模式在概念上与顶点相同,并且以coalesce()为中心。使用“现代” TinkerPop玩具图来演示:

gremlin> g.V().has('person','name','vadas').as('v').
           V().has('software','name','ripple').
           coalesce(__.inE('created').where(outV().as('v')),
                    addE('created').from('v').property('weight',0.5))
==>e[13][2-created->5]

在这里,我们在“ vadas”和“ ripple”之间添加一条边,但前提是该边不存在。此处的关键是检查coalesce()的第一个参数。

答案 1 :(得分:0)

接受的答案的性能不佳,因为它使用inE(...),这是一项昂贵的操作。

此查询是我在CosmosDB中使用的查询:

g.E(edgeId).
fold().
coalesce(
   unfold(),
   g.V(sourceId).
   has('pk', sourcePk).
   as('source').
   V(destinationId).
   has('pk', destinationPk).
   addE(edgeLabel).
   from('source').
   property(T.id, edgeId)
)

这使用每个顶点的id和partition键进行廉价查找。

答案 2 :(得分:0)

我一直在研究类似的问题,试图避免重复顶点或边。第一个是如何检查以确保不复制顶点的粗略示例:

            "g.V().has('word', 'name', '%s').fold()"
            ".coalesce(unfold(),"
            "addV('word')" 
            ".property('name', '%s')"
            ".property('pos', '%s')"
            ".property('pk', 'pk'))"
            % (re.escape(category_),re.escape(category_), re.escape(pos_))

第二个方法是我可以确保这两个方向都不是方向性边缘。我利用了两个合并语句,一个嵌套在另一个内:

        "x = g.V().has('word', 'name', '%s').next()\n"
        "y = g.V().has('word', 'name', '%s').next()\n"
        "g.V(y).bothE('distance').has('weight', %f).fold()"
        ".coalesce("
        "unfold(),"
        "g.addE('distance').from(x).to(y).property('weight', %f)"
        ")"
        % (word_1, word_2, weight, weight)

因此,如果边存在y-> x,则跳过产生另一个边。如果y-> x不存在,则进行测试以查看x-> y是否存在。如果没有,那么转到创建x-> y

的最终选项

让我知道这里是否有人知道更简洁的解决方案。我对gremlin还是很陌生,希望得到一个更干净的答案。不过,这个似乎足够。

实施上述提供的解决方案时,当我运行两次代码时,每次尝试都会产生一个优势,因为它只能在创建新优势之前测试一个方向。