简体   繁体   English

Gremlin 查询 - 如何消除嵌套合并

[英]Gremlin query - how to eliminate nested coalesce

I have person vertex, has_vehicle edge and vehicle vertex which models vehicle ownership use case.person顶点、 has_vehicle边和vehicle顶点,它们模拟车辆所有权用例。 The graph path is person -> has_vehicle -> vehicle .图形路径是person -> has_vehicle -> vehicle

I want to implement a Gremlin query which associates a vehicle to a person only if我想实现一个 Gremlin 查询,仅当

  • The person does not have a vehicle该人没有车辆

AND

  • The input vehicle is not associated with a person yet.输入的车辆尚未与人相关联。

I followed the fold-coalesce-unfold pattern and came out with following Gremlin query with nested coalesce我遵循了折叠合并展开模式,并提出了以下带有嵌套合并的 Gremlin 查询

g.V().hasLabel('person').has('name', 'Tom').as('Tom').outE('has_vehicle').fold().coalesce(
  __.unfold(), // check if Tom already have a vehicle
  g.V().has('vehicle', 123).as('Vehicle').inE('has_vehicle').fold().coalesce(
    __.unfold(), // check if vehicle 123 is already associated with a person
    __.addE('has_vehicle').from('Tom').to('Vehicle') // associate the vehicle to Tom
  )
)

Is there a way to eliminate the nested coalesce?有没有办法消除嵌套合并? If I have multiple criteria, it would be too complex to write the query.如果我有多个条件,那么编写查询就太复杂了。

This might be a case where a couple of where(not(...)) patterns, rather than nesting coalesce steps works well.这可能是几个where(not(...))模式而不是嵌套coalesce步骤的情况。 For example, we might change the query as shown below.例如,我们可能会更改查询,如下所示。

g.V().hasLabel('person').has('name', 'Tom').as('Tom').
      where(not(outE('has_vehicle'))).
  V().has('vehicle', 123).as('Vehicle').
      where(not(inE('has_vehicle'))).
  addE('has_vehicle').from('Tom').to('Vehicle')

So long as the V steps do not fan out and yield multiple Tom or Vehicle nodes that should work and is easy to extend by adding more to the where filters as needed.只要V步骤不散开并产生多个应该工作的 Tom 或 Vehicle 节点,并且可以根据需要通过向where过滤器添加更多节点来轻松扩展。

As as a side note, the not steps used above should work even if not wrapped by where steps, but I tend to find it just reads better as written.作为旁注,上面使用的not步骤即使没有被where步骤包装也应该有效,但我倾向于发现它只是读起来更好。

This rewrite does make an assumption that you are able to tolerate the case where Tom already has a car and the query just ends there.此重写确实假设您能够容忍 Tom 已经有车并且查询就此结束的情况。 In that case no vertex or edge will be returned.在这种情况下,不会返回任何顶点或边。 If you did a toList to run the query you would get an empty list back in that case however to indicate nothing was done.如果你执行了一个toList来运行查询,那么在这种情况下你会得到一个空列表,但是表示没有做任何事情。

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

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