【问题标题】:Conditionally set a property value on edge when adding a vertex [GREMLIN API]添加顶点时有条件地在边上设置属性值 [GREMLIN API]
【发布时间】:2019-10-31 09:53:11
【问题描述】:

我正在尝试添加一个顶点,该顶点将链接到另一个顶点,在它们的边缘之间具有条件属性值。

到目前为止,这是我想出的: - 这运行没有错误,但我无法得到任何结果。

g.V().has('label', 'product')
   .has('id', 'product1')
   .outE('has_image')
   .has('primary', true)
   .inV()
   .choose(fold().coalesce(unfold().values('public_url'), constant('x')).is(neq('x')))
       .option(true, 
           addV('image')
               .property('description', '')
               .property('created_at', '2019-10-31 09:08:15')
               .property('updated_at', '2019-10-31 09:08:15')
               .property('pk', 'f920a210-fbbd-11e9-bed6-b9a9c92913ef')
               .property('path', 'product_images/87wfMABXBodgXL1O4aIf6BcMMG47ueUztjNCkGxP.png')
               .V()
               .hasLabel('product')
               .has('id', 'product1')
               .addE('has_image')
               .property('primary', false))
       .option(false, 
           addV('image')
               .property('description', '')
               .property('created_at', '2019-10-31 09:08:15')
               .property('updated_at', '2019-10-31 09:08:15')
               .property('pk', 'f920a930-fbbd-11e9-b444-8bccc55453b9')
               .property('path', 'product_images/87wfMABXBodgXL1O4aIf6BcMMG47ueUztjNCkGxP.png')
               .V()
               .hasLabel('product')
               .has('id', 'product1')
               .addE('has_image')
               .property('primary', true))

我在这里所做的是试图在image 顶点和product 顶点之间设置新添加边的primary 属性,具体取决于product 是否已经连接到image,其中edge 已经将 primary 设置为 true。

如果product 已经有一个带有边缘属性的imageprimary:true,那么将链接到产品的新添加的图像应该具有带有属性primary:false 的边缘

种子 azure graphdb:

//add product vertex
g.addV('product').property(id, 'product1').property('pk', 'product1')

//add image vertex
g.addV('image').property(id, 'image1').property('public_url', 'url_1').property('pk', 'image1');


//link products to images

g.V('product1').addE('has_image').to(V('image1')).property('primary', true)

【问题讨论】:

    标签: graph-databases gremlin azure-cosmosdb-gremlinapi


    【解决方案1】:

    我很惊讶您的遍历运行没有错误,因为我遇到了几个关于您使用 option() 的语法问题以及您混合使用 T.id 和“id”的属性键(后者可能是您问题的一部分,为什么这不能按原样工作,但我不完全确定)。当然,我没有在 CosmosDB 上进行测试,所以也许他们对 Gremlin 语言如此随意。

    无论如何,假设我正确地遵循了您的解释,我认为有一种方法可以大大简化您的 Gremlin。我想你只需要这个:

    g.V('product1').as('p').
      addV('image').
        property('description', '').
        property('created_at', '2019-10-31 09:08:15').
        property('updated_at', '2019-10-31 09:08:15').
        property('pk', 'f920a210-fbbd-11e9-bed6-b9a9c92913ef').
        property('path', 'product_images/87wfMABXBodgXL1O4aIf6BcMMG47ueUztjNCkGxP.png').
        addE('has_image').
          from('p').
        property('primary', choose(select('p').outE('has_image').values('primary').is(true), 
                              constant(false), constant(true)))
    

    现在,我想说这是 Gremlin 最惯用的方法,因为我还没有在 CosmosDB 上测试过,所以我不能说这种方法是否适合你,但也许看看我下面的控制台会话,你可以看到它确实满足您的期望:

    gremlin> g.V('product1').as('p').
    ......1>   addV('image').
    ......2>     property('description', '').
    ......3>     property('created_at', '2019-10-31 09:08:15').
    ......4>     property('updated_at', '2019-10-31 09:08:15').
    ......5>     property('pk', 'f920a210-fbbd-11e9-bed6-b9a9c92913ef').
    ......6>     property('path', 'product_images/87wfMABXBodgXL1O4aIf6BcMMG47ueUztjNCkGxP.png').
    ......7>     addE('has_image').
    ......8>       from('p').
    ......9>     property('primary', choose(select('p').outE('has_image').values('primary').is(true), constant(false), constant(true)))
    ==>e[31][product1-has_image->25]
    gremlin> g.E().elementMap()
    ==>[id:31,label:has_image,IN:[id:25,label:image],OUT:[id:product1,label:product],primary:true]
    gremlin> g.V('product1').as('p').
    ......1>   addV('image').
    ......2>     property('description', '').
    ......3>     property('created_at', '2019-10-31 09:08:15').
    ......4>     property('updated_at', '2019-10-31 09:08:15').
    ......5>     property('pk', 'f920a210-fbbd-11e9-bed6-b9a9c92913ef').
    ......6>     property('path', 'product_images/87wfMABXBodgXL1O4aIf6BcMMG47ueUztjNCkGxP.png').
    ......7>     addE('has_image').
    ......8>       from('p').
    ......9>     property('primary', choose(select('p').outE('has_image').values('primary').is(true), constant(false), constant(true)))
    ==>e[38][product1-has_image->32]
    gremlin> g.E().elementMap()
    ==>[id:38,label:has_image,IN:[id:32,label:image],OUT:[id:product1,label:product],primary:false]
    ==>[id:31,label:has_image,IN:[id:25,label:image],OUT:[id:product1,label:product],primary:true]
    gremlin> g.V('product1').as('p').
    ......1>   addV('image').
    ......2>     property('description', '').
    ......3>     property('created_at', '2019-10-31 09:08:15').
    ......4>     property('updated_at', '2019-10-31 09:08:15').
    ......5>     property('pk', 'f920a210-fbbd-11e9-bed6-b9a9c92913ef').
    ......6>     property('path', 'product_images/87wfMABXBodgXL1O4aIf6BcMMG47ueUztjNCkGxP.png').
    ......7>     addE('has_image').
    ......8>       from('p').
    ......9>     property('primary', choose(select('p').outE('has_image').values('primary').is(true), constant(false), constant(true)))
    ==>e[45][product1-has_image->39]
    gremlin> g.E().elementMap()
    ==>[id:38,label:has_image,IN:[id:32,label:image],OUT:[id:product1,label:product],primary:false]
    ==>[id:45,label:has_image,IN:[id:39,label:image],OUT:[id:product1,label:product],primary:false]
    ==>[id:31,label:has_image,IN:[id:25,label:image],OUT:[id:product1,label:product],primary:true]
    

    如果看起来正确,但在 CosmosDB 中无法正常工作,那是因为第 9 行使用了 Traversal 作为 property() 的参数,CosmosDB 尚不支持该参数。补救方法是简单地将那条线反转一下:

    g.V('product1').as('p').
      addV('image').
        property('description', '').
        property('created_at', '2019-10-31 09:08:15').
        property('updated_at', '2019-10-31 09:08:15').
        property('pk', 'f920a210-fbbd-11e9-bed6-b9a9c92913ef').
        property('path', 'product_images/87wfMABXBodgXL1O4aIf6BcMMG47ueUztjNCkGxP.png').
        addE('has_image').
          from('p').
        choose(select('p').outE('has_image').values('primary').is(true), 
               property('primary', false), 
               property('primary', true))
    

    我发现这种方法的可读性稍差,因为 property()addE() 不一致,但它并不是一个糟糕的选择。

    【讨论】:

    • 我喜欢你的回答,因为它简化了我的查询,但它在 cosmosdb 中还不起作用。它说Gremlin Query Execution Error: Cannot create ValueField on non-primitive type GraphTraversal
    • 我按照here的建议尝试了另一种方法,我使用了coalesce而不是你最后使用的选择遍历:coalesce(select('p').outE('has_image').constant(true), constant(false))但仍然是同样的错误。
    • 看来 azure cosmos db 还没有支持这个。看here
    猜你喜欢
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 2014-12-25
    • 2020-09-26
    相关资源
    最近更新 更多