Gremlin 小精灵:如果我的查询不能以V()或E()开头怎么办?

Gremlin 小精灵:如果我的查询不能以V()或E()开头怎么办?,gremlin,tinkerpop,tinkerpop3,gremlin-server,gremlinjs,Gremlin,Tinkerpop,Tinkerpop3,Gremlin Server,Gremlinjs,对我的项目执行的第一个查询运行在一个可能为空的数据库上,如果尚未创建顶点,则会创建一些顶点,因此我的查询不能以V()或E()开始,因为数据库可能为空,也不能以addE()开始,因为首先我需要检查是否未创建边,我使用inject()找到了以下解决方案,但它看起来像一个黑客: g.inject("").union( coalesce(V().has("question", "questionId", 0), addV("q

对我的项目执行的第一个查询运行在一个可能为空的数据库上,如果尚未创建顶点,则会创建一些顶点,因此我的查询不能以
V()
E()
开始,因为数据库可能为空,也不能以
addE()
开始,因为首先我需要检查是否未创建边,我使用
inject()
找到了以下解决方案,但它看起来像一个黑客:

g.inject("").union(
    coalesce(V().has("question", "questionId", 0), addV("question").property("questionId", 0)),
    coalesce(V().has("question", "questionId", 1), addV("question").property("questionId", 1)),
    coalesce(V().has("question", "questionId", 2), addV("question").property("questionId", 2))
)

有没有一种方法可以以优雅的方式编写此脚本,而不需要任何看起来很粗糙的东西?

可以通过所描述的
fold()/unfold()
模式使用upsert模式来处理此场景。这看起来像下面的代码:

g.V().
  has("question", "questionId", 0).
  fold().
  coalesce(unfold(), addV("question").property("questionId", 0)).
  V().
  has("question", "questionId", 1).
  fold().
  coalesce(unfold(), addV("question").property("questionId", 1)).
  V().
  has("question", "questionId", 2).
  fold().
  coalesce(unfold(), addV("question").property("questionId", 2))

也许我只是做了太长时间的Gremlin,但是
g.inject(0)
对我来说并不是一个黑客。当我认为必须在遍历流中有一些东西才能首先有一个流时,有一些关于注入一次性值的东西对我来说是有意义的。虽然我相信您在下面有一个使用
V()
的答案,但在您不能使用的情况下,还有什么其他语法可能更好呢?我同意,与答案中的解决方案相比,我的解决方案感觉不太像黑客。当你使用一个完全不同的用途的工具来解决问题时,我认为是一个黑客。inject的目的是将数据添加到遍历中,而不是绕过一个不会以其他方式启动的查询。我认为gremlin应该实现类似于
g.startentytraversal()
的东西,这是专门为这种需要而设计的,否则它感觉像是一个黑客。我只是想说清楚
inject(0)
并没有真正困扰我,bechbd的答案也没有,但你不是第一个不喜欢
inject(0)的人
所以我认为值得讨论一下,看看您是否有任何想法。我认为显式的
startentry()
有点过分地破坏了预期的遍历语义。然而,我确实想知道像
union()
coalesce()
这样的步骤是否可以作为开始步骤,那么
g.coalesce(V().has('name','alice')、addV().property('name','alice'))
或类似的步骤是可能的。我不确定这意味着什么,但我会记下来进一步思考。谢谢。可能没有其他选择,但这对我来说也像是一个黑客行为,因为你需要执行fold()和unfold(),你在添加额外的计算,并使用一些完全不同的用途,只是因为如果你不添加它,你就无法编写queryIMO,
fold()。coalesce(unfold(),…)
模式更有效“Gremlin ic”(类似于python的“pythonic”),因为查询模式实际上是在执行一个图遍历,以更命令式的方式执行条件写入。其中as
inject(0)
或(如果支持)以
coalesce()开头
直接将尝试以更具声明性的方式编写此查询。使用
折叠()
/
展开()
也可能不会添加额外的计算。每个TinkerPop graph数据库将以不同的方式解析、优化和执行这些查询。许多人将优化此模式,因为这是众所周知的。