Gremlin MergeV 用于更新现有元素的属性和单一基数。

huangapple go评论68阅读模式
英文:

Gremlin MergeV To Update an Existing Element's property and Single Cardinality

问题

我正在使用Amazon Neptune和Gremlin-go来满足我们的图数据库需求。我正在编写代码,使用g.mergeV()来插入/更新(upsert)一个元素。然而,当找到匹配项并更新属性时,新值会被添加到值列表中。我希望将正在更新的属性设置为single(基数),这样在任何给定时间它只会有一个值。这是我的代码:

g.mergeV(['firstname': 'fname']).
    option(onCreate, [(T.label): 'Someone','lastname': 'lname']).
    option(onMatch, ['lastname': 'lname1']))

我希望更新后的值看起来像这样:

{'firstname': ['fname'], 'lastname': ['lname1']}

但是,更新后的值看起来像这样:

{'firstname': ['fname'], 'lastname': ['lname','lname1']}

不幸的是,Neptune的默认属性基数是一个列表。我希望如果找到匹配项,使用property()方法可以起作用,但是出现了以下错误:

g.mergeV(['firstname': 'fname']).
    option(onCreate, [(T.label): 'Someone','lastname': 'lname']).
    option(onMatch, __.property(single, ['lastname': 'lname1'])))

"detailedMessage": "com.amazon.neptune.tinkerpop.structure.NeptuneVertex cannot be cast to java.util.Map"

我还尝试了使用fold/coalesce/unfold的方法,但是如果找到记录,值不会被更新:

g.V().hasLabel("Someone").
      has("firstname", "fname").
      has("lastname", "lname").
      fold().
      coalesce(unfold(), 
               __.addV("Someone").property(single, ["firstname": "fname", "lastname": "lname1"]))

只要是upsert,我可以尝试使用其他方法。

英文:

I am using Amazon Neptune with Gremlin-go for our Graph Database needs. I am working on code to insert/update (upsert) an element with g.mergeV(). However, when a match is found, and a property gets updated, the new value is added to a value-list. I wanted to set the property that is getting updated as a single (Cardinality), so at any given time it will have only one value. This is my code

g.mergeV(['firstname': 'fname']).
    option(onCreate, [(T.label): 'Someone','lastname': 'lname']).
    option(onMatch, ['lastname': 'lname1']))

I would like the values on update to look like this

{'firstname': ['fname'], 'lastname': ['lname1']}

But, values after update look like this

{'firstname': ['fname'], 'lastname': ['lname','lname1']}

Unfortunately, Neptune's default property Cardinality is a List. I was hoping using the property() would work if a match is found, however get this error

g.mergeV(['firstname': 'fname']).
    option(onCreate, [(T.label): 'Someone','lastname': 'lname']).
    option(onMatch, __.property(single, ['lastname': 'lname1'])))

"detailedMessage": "com.amazon.neptune.tinkerpop.structure.NeptuneVertex cannot be cast to java.util.Map"

I have also tried the fold/coalesce/unfold route, but values don't get updated if a record is found

g.V().hasLabel("Someone").
      has("firstname", "fname").
      has("lastname", "lname").
      fold().
      coalesce(unfold(), 
               __.addV("Someone").property(single, ["firstname": "fname", "lastname": "lname1"]))

I am open to using another way, as long as it is upsert.

答案1

得分: 1

几点评论。

  1. 亚马逊海王星默认使用的基数实际上是 Set 而不是 List。
  2. 要使用查询的 coalesce 形式,你需要为左侧提供一个不仅仅是 unfold 的操作,因为如果顶点已经存在,那么这将是执行的路径。所以查询应该是这样的:
g.V().hasLabel("Someone").
      has("firstname", "fname").
      has("lastname", "lname").
      fold().
      coalesce(unfold().property(single,"firstname","Newname"), 
               addV("Someone").property(single, ["firstname": "fname", "lastname": "lname1"]))
  1. mergeV 查询可以工作。你只需要使用稍微不同的形式,如下所示。sideEffect 执行实际的更新操作,constant([:]) 生成一个空映射,因为没有其他需要更改的内容。
g.mergeV(["firstname":"firstname"]).
   option(Merge.onMatch,sideEffect(property(single,"firstname","Newname")).constant([:]))

注意 你需要使用引擎版本为 1.2.1.0.R2 或更高的 Amazon Neptune 才能使 sideEffect 版本的查询工作。

英文:

A few comments.

  1. The default Cardinality used by Amazon Neptune is actually Set and not List
  2. To use the coalesce form of the query, you need to provide an action more than just unfold for the LHS as that will be the path taken if the vertex already exists. So the query will be something like this:
g.V().hasLabel("Someone").
      has("firstname", "fname").
      has("lastname", "lname").
      fold().
      coalesce(unfold().property(single,"firstname","Newname"), 
               addV("Someone").property(single, ["firstname": "fname", "lastname": "lname1"]))
  1. The mergeV query can be made to work. You just need to use a slightly different form along these lines. The sideEffect performs the actual update and the constant([:]) generates an empty map as there are no more changes needed.
g.mergeV(["firstname":"firstname"]).
   option(Merge.onMatch,sideEffect(property(single,"firstname","Newname")).constant([:]))

Note You will need to be running Amazon Neptune with an engine version of 1.2.1.0.R2 or higher for the sideEffect version of the query to work.

huangapple
  • 本文由 发表于 2023年5月9日 03:42:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76203885.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定