0

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

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"
    },
    ]
  }
}

但这让我无法预测结果。

我如何才能更新数据并对其进行投影?

我尝试过的其他事情:

  • barrier()在步骤之后添加drop()步骤,没有用
  • barrier()在步骤之后添加sideEffect()步骤,没有用
  • barrier()在步骤之前添加一个步骤project(),没有用
  • 与上述三个相同,但.fold().unfold()相反,没有用
  • project()将步骤替换为optional(g.V("1").project("Tags").by(values("Tags")))- 这一步通过重新获取顶点来工作,但成本很高。
4

1 回答 1

2

在这种情况下,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]]

也许您应该尝试使用我的by()调制器进行查询,project()看看添加的内容是否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]]

看看这是否有什么不同。

于 2020-03-26T18:00:37.503 回答