首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Gremlin Python -如果边界不存在,则向边缘创建添加未知数量的属性。

Gremlin Python -如果边界不存在,则向边缘创建添加未知数量的属性。
EN

Stack Overflow用户
提问于 2019-10-07 09:28:06
回答 2查看 1K关注 0票数 1

该查询应针对以下内容:

如果存在两个顶点之间的边,则为

  • :返回边缘
  • :创建边缘,从dict设置属性并返回边缘。

如果traversal是一个原始的遍历,下面的操作是有效的。如果traversal已经包含了其他一些步骤(例如创建顶点),那么它就会崩溃,导致以下错误。

代码语言:javascript
复制
properties = {"p1": "p1_value", "p2": "p2_value"}

traversal.V().inject(properties).as_(props_label).
V().has("uuid",from_uuid).as_(from_label).
V().has("uuid",to_uuid).as_(to_label).
coalesce(inE(edge_label).where(outV().
as_(from_label)),addE(edge_label).
from_(from_label).as_(e_label).select(props_label).
unfold().as_(kv_label).select(e_label).
property(select(kv_label).by(Column.keys),select(kv_label).by(Column.values))).iterate()
代码语言:javascript
复制
gremlin_python.driver.protocol.GremlinServerError: 500: The provided object does not have accessible keys: class org.janusgraph.graphdb.vertices.StandardVertex

如果我在iterate()之前遍历injecting,它就能工作。但是,出于性能原因,我想避免迭代。

有什么想法吗?

编辑:

我做了更多的测试。预先添加顶点是有效的。在同一个查询中添加它们不会。

这样做是可行的:

代码语言:javascript
复制
gremlin> g.addV("TestType").property("name", "1")
==>v[2302192]
gremlin> g.addV("TestType").property("name", "2")
==>v[2326704]
gremlin> g.inject(["p1": "v1", "p2": "v2"]).unfold().as("props").V(2302192).as("from").V(2326704).as("to").coalesce(inE("DEPENDS_ON").where(outV().as("from")), addE("DEPENDS_ON").from("from").property(select("props").by(keys), select("props").by(values)))
==>e[187by-1dcds-1lh-1dvao][2302192-DEPENDS_ON->2326704]
==>e[187by-1dcds-1lh-1dvao][2302192-DEPENDS_ON->2326704]

这是失败的:

代码语言:javascript
复制
gremlin> g.addV("TestType").property("name", "1").addV("TestType").property("name", "2").inject(["p1": "v1", "p2": "v2"]).unfold().as("props").V().has("name", "1").as("from").V().has("name", "2").as("to").coalesce(inE("DEPENDS_ON").where(outV().as("from")), addE("DEPENDS_ON").from("from").property(select("props").by(keys), select("props").by(values))).dedup()
The provided object does not have accessible keys: class org.janusgraph.graphdb.vertices.StandardVertex
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-07 11:36:36

作为初始点,您不需要遍历中的第一个V。您只需要从inject()开始。如果以V()开头,则对图中的每个顶点执行以下步骤。

尽管如此,我不认为您的遍历有任何问题,而且一旦我将它改编成现代玩具图,它就可以在TinkerGraph上正常工作了:

代码语言:javascript
复制
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> properties = [p1: "p1_value", p2: "p2_value"]
==>p1=p1_value
==>p2=p2_value
gremlin> g.inject(properties).as('props_label').
......1>   V().has("name",'marko').as('from_label').
......2>   V().has("name",'josh').as('to_label').
......3>   coalesce(inE('knows').where(outV().as('from_label')),
......4>            addE('knows').from('from_label').as('e_label').select('props_label').
......5>              unfold().as('kv_label').select('e_label').
......6>              property(select('kv_label').by(Column.keys),
......7>                       select('kv_label').by(Column.values)))
==>e[8][1-knows->4]
gremlin> g.inject(properties).as('props_label').
......1>   V().has("name",'peter').as('from_label').
......2>   V().has("name",'vadas').as('to_label').
......3>   coalesce(inE('knows').where(outV().as('from_label')),
......4>            addE('knows').from('from_label').as('e_label').select('props_label').
......5>              unfold().as('kv_label').select('e_label').
......6>              property(select('kv_label').by(Column.keys),
......7>                       select('kv_label').by(Column.values)))
==>e[13][6-knows->2]
==>e[13][6-knows->2]

您可能希望在此遍历中获得dedup()结果,因为在第5行给定其unfold()时,您将为映射中的每个属性键获得一个结果。

您所得到的错误是服务器端的错误,我认为gremlinpython没有问题。它指出了select('kv_label').by(Column.keys)试图访问JanusGraph StandardVertex对象的情况。考虑到您最新的问题,我可以很容易地在TinkerGraph中重新创建这个问题:

代码语言:javascript
复制
gremlin> g.addV("TestType").property("name", "1").
......1>   addV("TestType").property("name", "2").
......2>   inject(["p1": "v1", "p2": "v2"]).
......3>   unfold().as("props").
......4>   V().has("name", "1").as("from").
......5>   V().has("name", "2").as("to").
......6>   coalesce(inE("DEPENDS_ON").where(outV().as("from")), 
......7>            addE("DEPENDS_ON").from("from").
......8>              property(select("props").by(keys), select("props").by(values))).dedup()
The provided object does not have accessible keys: class org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex
Type ':help' or ':h' for help.
Display stack trace? [yN]n

这是一个非常不同的遍历与您最初的问题,这就是为什么我不能重新创建它。您期待的只是来自流中的inject()的键/值对,但实际上它还有其他的内容:

代码语言:javascript
复制
gremlin> g.addV("TestType").property("name", "1").
......1>   addV("TestType").property("name", "2").
......2>   inject(["p1": "v1", "p2": "v2"]).
......3>   unfold()
==>p1=v1
==>p2=v2
==>v[2]

v[2]到达select("props").by(keys)时,您将得到我描述的异常。您可以通过将inject()移动到起始位置或使用withSideEffect()来修复它。

代码语言:javascript
复制
gremlin> g.inject(["p1": "v1", "p2": "v2"]).as('props').
......1>   addV("TestType").property("name", "1").
......2>   addV("TestType").property("name", "2").
......3>   V().has("name", "1").as("from").
......4>   V().has("name", "2").as("to").
......5>   coalesce(inE("DEPENDS_ON").where(outV().as("from")), 
......6>            addE("DEPENDS_ON").from("from").as('e').
......7>              select('props').
......8>              unfold().as('kv').
......9>              select('e').
.....10>              property(select("kv").by(keys), select("kv").by(values))).dedup()
==>e[4][0-DEPENDS_ON->2]
gremlin> g.withSideEffect('props', ["p1": "v1", "p2": "v2"]).
......1>   addV("TestType").property("name", "1").
......2>   addV("TestType").property("name", "2").
......3>   V().has("name", "1").as("from").
......4>   V().has("name", "2").as("to").
......5>   coalesce(inE("DEPENDS_ON").where(outV().as("from")), 
......6>            addE("DEPENDS_ON").from("from").as('e').
......7>              select('props').
......8>              unfold().as('kv').
......9>              select('e').
.....10>              property(select("kv").by(keys), select("kv").by(values))).dedup()
==>e[4][0-DEPENDS_ON->2]

我不知道哪一个更直观。当我需要一些东西开始遍历时,我倾向于选择inject(),但是您需要addV()在开始时放置对象,所以inject()在这里看起来很笨拙,特别是因为addV()只是替换了给定的Map。在这种情况下,我认为使用withSideEffect()会更明确地告诉阅读这篇文章的人其意图是什么。

票数 2
EN

Stack Overflow用户

发布于 2019-10-22 15:29:10

只是为了供将来可能偶然发现这件事的人参考。我找到了一个更简单的解决方案,使用匿名遍历而不是注入:

代码语言:javascript
复制
properties = {"some key": "some value", "etc": "bla"}

# prepare the add vertex sub traversal
add_vertex_traversal = addV(label)
for k, v in properties.items():
    add_vertex_traversal = add_vertex_traversal.property(k, v)

g.V().has('some_prop', "some_value").fold().coalesce(unfold(),add_vertex_traversal)) 
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58266802

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档