【问题标题】:How can I set the values of a list property in gremlin (CosmosDb) and project it in the query result?如何在 gremlin (CosmosDb) 中设置列​​表属性的值并将其投影到查询结果中?
【发布时间】:2020-03-26 14:10:24
【问题描述】:

我有一个具有列表属性的顶点,我想替换所述属性中的值并以特定格式投影出结果。 对于上下文,我们假设以下数据:

g.AddV("Post").property("id", "1")
  .property(list, "Tags", "gremlin")
  .property(list, "Tags", "new")

我希望能够设置Tags 属性。 到目前为止我尝试过的:

g.V("1")
  .sideEffect( properties("Tags").drop() )
  .property(list, "Tags", "gremlin")
  .property(list, "Tags", "closed")
  .property(list, "Tags", "solved")
  .project("Tags").By(values("Tags"))

我期望的是以下内容

{
  "Tags": [
    "gremlin",
    "closed",
    "solved",
  ]
}

但是我得到了错误Project By: Next: The provided traverser of key "Tags" maps to nothing. 所以看起来好像Tags 属性被完全删除了。 如果我之后做一个查询

g.V("1").project("Tags").By(values("Tags"))

我得到了预期的结果:

{
  "Tags": [
    "gremlin",
    "closed",
    "solved",
  ]
}

所以数据肯定已经改变了。 如果我尝试不投影,则结果包含新值。

g.V("1")
  .sideEffect( properties("Tags").drop() )
  .property(list, "Tags", "gremlin")
  .property(list, "Tags", "closed")
  .property(list, "Tags", "solved")

导致:

{
  "id": "1",
  "label": "Post",
  "type": "vertex",
  "properties": {
    "Tags": [
    {
      "id": "4eaf5599-511c-4245-aaf8-15c828073fac",
      "value": "gremlin"
    },
    {
      "id": "75e3ad96-a503-4608-a675-e28f3ffc2ab4",
      "value": "closed"
    },
    {
      "id": "aea1a33c-bd8e-47bb-b294-f01db8642db5",
      "value": "solved"
    },
    ]
  }
}

但这让我无法预测结果。

我怎样才能既更新数据又进行投影?

我尝试过的其他事情:

  • drop() 步骤之后添加barrier() 步骤无效
  • sideEffect() 步骤之后添加barrier() 步骤无效
  • project() 步骤之前添加barrier() 步骤,无效
  • 和上面三个一样,但是用.fold().unfold()代替,没有用
  • project() 步骤替换为optional(g.V("1").project("Tags").by(values("Tags"))) - 这一步通过重新获取顶点来工作,但成本很高。

【问题讨论】:

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


    【解决方案1】:

    在这种情况下,CosmosDB 可能会发生一些事情,这意味着您可能需要从他们那里获得特定的帮助。请注意,您的遍历(几乎就像它所写的那样)与 TinkerGraph 一起工作,这是 Gremlin 应该如何工作的参考实现:

    gremlin> g = TinkerFactory.createTheCrew().traversal()
    ==>graphtraversalsource[tinkergraph[vertices:6 edges:14], standard]
    gremlin> g.V().has('person','name','marko').
    ......1>   sideEffect(properties("location").drop()).
    ......2>   property(list,'location','bombay').
    ......3>   property(list,'location','calcutta').
    ......4>   project('location').
    ......5>     by(values('location').fold())
    ==>[location:[bombay,calcutta]]
    

    也许您应该在project() 上使用我的by() 调制器尝试查询,看看添加的fold() 是否有任何不同。顺便说一句,我不希望没有fold() 的遍历会返回您所说的返回。如果我尝试这样做,请注意 TinkerGraph 会发生什么:

    gremlin> g.V().has('person','name','marko').
    ......1>   sideEffect(properties("location").drop()).
    ......2>   property(list,'location','bombay').
    ......3>   property(list,'location','calcutta').
    ......4>   project('location').
    ......5>     by(values('location'))
    ==>[location:bombay]
    

    project() 步骤替换为optional(g.V("1").project("Tags").by(values("Tags"))) - 这一步通过重新获取顶点来工作,但成本很高。

    以上是一个有趣的观点,虽然我个人不喜欢使用g 来生成子遍历,所以更喜欢生成为optional(V("1").project("Tags").by(values("Tags"))) 的匿名遍历。这让我想知道 CosmosDB 是否不反映当前遍历器中的突变,这就是为什么当您通过重新查询刷新时得到您正在寻找的结果的原因。我很惊讶中间遍历查找的成本很高,因为它是按元素 id 进行的查找,并且应该是在图中查找内容的最快方法。也就是说,您必须在同一次遍历中多次查找Vertex 并不是很好。

    出于好奇,您可以尝试 valueMap(true) 而不是 project() 作为另一个测试,看看这是否会触发任何不同的行为。

    要尝试的另一件事可能是使用union() 而不是sideEffect()

    gremlin> g.V().has('person','name','marko').
    ......1>   union(properties("location").drop(), identity()).
    ......2>   property(list,'location','bombay').
    ......3>   property(list,'location','calcutta').
    ......4>   project('location').
    ......5>     by(values('location').fold())
    ==>[location:[bombay,calcutta]]
    

    看看这是否有什么不同。

    【讨论】:

    • 使用by(values('Tags')) 会产生以下结果:Unsupported Error: Gremlin op does not support by(traversal) 我同样怀疑 CosmosDB 不反映突变,但是如果我这样做 g.V('1').property(list, 'Tags', 'foo').values('Tags'),结果包括新添加的标签。我试过valueMap(true),有趣的是它包含了标签。该问题似乎仅在涉及drop() 时发生。关于投影格式和fold() 的另一个有趣点。
    • 好吧,看起来你肯定会在他们的 Gremlin 实施中遇到不一致的情况。我添加了另一个选项来尝试,但我感觉您将被困在(1)两个单独的遍历或(2)使用中间遍历 V() 重新查询。当我不完全确定 CosmosDB 真正支持什么以及不支持什么时,也很难想到解决方法。我再次建议您向他们提出这个问题。
    • 不幸的是,这会产生Gremlin Query Compilation Error。不过,感谢您的时间。我将继续调查并尝试联系 MS。如果我找到解决方案,我会更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 2021-11-20
    • 2022-01-18
    • 2019-08-11
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多