简体   繁体   English

UPSERT 具有 Gremlin 属性的优势

[英]UPSERT an edge with properties with Gremlin

I'm trying to upsert an edge (insert if it does not exist but update if it does) with properties in Gremlin via a single query.我正在尝试通过单个查询在 Gremlin 中使用属性更新边缘(如果不存在则插入,但如果存在则更新)。

I have this which adds a manages edge with a duration property between two vertices with id of Amy and John .我有这个,它在 id 为AmyJohn的两个顶点之间添加了一个带有duration属性的manages边。

gE().where(outV().has('id','Amy')).where(inV().has('id','John')).fold().coalesce(unfold(),gV('Amy').as('a').V('John').addE('manages').from('a').property('duration','1year')) . gE().where(outV().has('id','Amy')).where(inV().has('id','John')).fold().coalesce(unfold(),gV('Amy').as('a').V('John').addE('manages').from('a').property('duration','1year'))

The query does do an upsert, but if I change the value of the duration property, remove the duration property, or add other properties, the property changes are not reflected on the edge.该查询确实执行了 upsert,但是如果我更改了duration属性的值、删除了duration属性或添加了其他属性,则属性更改不会反映在边缘上。

I want to be able to change the value of the duration property without adding a new edge or having to remove the old one.我希望能够更改duration属性的值,而无需添加新边缘或删除旧边缘。

I'm fairly new to Gremlin so please share any advice which may help.我对 Gremlin 还很陌生,所以请分享任何可能有帮助的建议。

I'm not sure it matters but the underlying DB is an Azure Cosmos DB.我不确定这是否重要,但底层数据库是 Azure Cosmos DB。

To always have the property change apply whether the edge exists or is created, you just need to move the property step to after the coalesce :要始终使属性更改适用于边缘是否存在或已创建,您只需将property步骤移动到coalesce之后:

g.E().
  where(outV().has('id', 'Amy')).
  where(inV().has('id', 'John')).
  fold().
  coalesce(
    unfold(),
    g.V('Amy').as('a').
      V('John').
      addE('manages').from('a')).
   property('duration', '1year')

However, that said, there are a few observations that can be made about the query.但是,也就是说,可以对查询进行一些观察。 Starting with gE() is likely to be inefficient and using gV() mid traversal should be avoided, and where necessary just V() used.gE()开始可能效率低下,应避免使用gV()中间遍历,必要时只使用V()

If 'John" and 'Amy' are unique ID's you should take advantage of that along these lines:如果 'John" 和 'Amy' 是唯一 ID,您应该按照以下方式利用它:

g.V('Amy').
  outE().where(inV().hasId('John')).
  fold().
  coalesce(
    unfold(),
    addE('manages').from(V('Amy')).to(V('John'))).
  property('duration', '1year')

Two additions to Kevin's answer :凯文的回答有两个补充:

  1. I think you need to specify the edge label in outE , otherwise the unfold may return other relationships present between the two vertices, and these will be updated with the property, rather than triggering the addE of the new edge.我认为您需要在 outE 中指定边outE ,否则unfold可能会返回两个顶点之间存在的其他关系,这些关系将使用属性进行更新,而不是触发新边的 addE。 Specifying the edge label should ensure the length of the folded array is 0 in the case of INSERT and 1 in the case of UPDATE.指定边 label 应确保折叠数组的长度在 INSERT 的情况下为 0,在 UPDATE 的情况下为 1。

  2. For Cosmos DB Gremlin API, use the anonymous class __ when not using g对于 Cosmos DB Gremlin API,在不使用g时使用匿名 class __

g.V('Amy').
  outE('manages').where(inV().hasId('John')).
  fold().
  coalesce(
    unfold(),
    __.addE('manages').from(__.V('Amy')).to(__.V('John'))).
  property('duration', '1year')

More detailed example here .更详细的例子在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM