了解使用Gremlin-Python添加边缘的不同方法 [英] Understanding different methods for adding edges with Gremlin-Python

查看:115
本文介绍了了解使用Gremlin-Python添加边缘的不同方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解方法的差异,以及在Gremlin-Python中添加边缘(在现有顶点之间)的最佳语法.

在这里阅读了几篇关于SO的文章之后,我将发现的一些不同方法细分为几个问题.

非常感谢您的任何提前反馈!

1)在创建边缘时,向边缘添加属性的最佳顺序是什么?:哪个是更好的选择(以防万一之间有显着差异)? /p>

g.V().property("prop1", "prop1_val").as_("a")
 .V().property("prop2", "prop2_val").as_("b")
 .addE("some_relationship")
# rest of traversal option 1:
 .property("prop1_val_weight", 0.1d)
 .from_("a").to("b")
# rest of traversal option 2:
 .from_("a").to("b")
 .property("prop1_val_weight", 0.1d)

2)"__.V()" 的目的和正确用法是什么?

g.V().property("prop1", "prop1_val")
 .as_("a").V().property("prop2", "prop2_val")
 .as_("b").addE("some_relationship")
 .property("prop1_val_weight", 0.1d)
# AND THEN:
 .from_("a").to("b")
# VERSUS: 
 .from_(__.V("a")).to(__.V("b"))

3)使用属性"与属性" 有什么区别:

g.V().property("prop1", "prop1_val").as_("a")
# VERSUS:
g.V().properties("prop1", "prop1_val").as_("a")
# REST OF THE TRAVERSAL:
 .V().property("prop2", "prop2_val").as_("b")
 .addE("some_relationship")
 .property("prop1_val_weight", 0.1d)
 .from_("a").to("b")

4)如果没有指定.to()"个顶点/顶点,并且在这种情况下,也使用"__.V()",会发生什么情况:

g.V().property("prop1", "prop1_val").as_("a")
 .V().property("prop2", "prop2_val").as_("b")
 .addE("some_relationship").to(__.V()
 .has("prop2", "prop2_val"))

5)在遍历结束时添加".profile()" 的原因是什么?

g.V('Alice').as_('v').V('Bob').coalesce(inE('spokeWith')
 .where(outV().as_('v')).addE('spokeWith')
 .property('date', 'xyz').from_('v'))
 .profile()

6)在添加边(例如在5 ​​^^遍历中使用边)的同时使用"coalesce"步骤的正确用法以及通常的附加优点是什么?

7)和一些一般性问题:

  • 还寻找标签的优点是什么,例如"g.V().has(" LABEL1," prop1," prop1_val).as _(" a)[etc.]"
  • 在将遍历分配给变量(例如,"t = gV()...")后,只需几个步骤,然后仅调用一次就足够了,最后调用"t.iterate()"还是应该这样每次都做?
  • 在脚本的哪一点应该调用"tx.commit()":在多次遍历结束时仅调用一次就足够了吗?

解决方案

1)在创建边缘的同时向其添加属性的最佳顺序是什么

从操作上看,我认为没有最佳顺序",但就我个人而言,最好将from()to()紧跟在addE()之后.

2)"__.V()"的目的和正确用法是什么?

您不能以这种方式使用遍历V().这样做基本上就是说:在图的顶点上找到不存在的"a"的T.id.在您的情况下,"a"是仅位于该遍历范围局部的步骤标签.

3)使用属性"与属性"有什么区别:

有很大的不同. property(k,v)是一个变异步骤,通过添加/更新具有指定值的属性键来修改流中的图形元素. properties(k...)获取由提供的键指定的属性列表(即读取操作).

4)如果未指定".to()"个顶点/顶点,并且在这种情况下,也使用"__.V()"

,会发生什么情况?

为什么不启动Gremlin Console并查看:

gremlin> g.addV().addE('self')
==>e[17][16-self->16]
gremlin> g.addV().as('z').addE('self').property('x','y').from('z').to(V().has('person','name','nobody'))
The provided traverser does not map to a value: v[20]->[TinkerGraphStep(vertex,[~label.eq(person), name.eq(nobody)])]
Type ':help' or ':h' for help.
Display stack trace? [yN]

5)在遍历末尾添加".profile()"的原因是什么?

出于相同原因,您需要分析代码或解释SQL查询-以便更详细地了解该代码在做什么.也许您需要查看索引是否被正确使用,或者找出执行最长步骤所需的步骤,以查看是否可以更好地优化遍历.

6)在添加边(例如在5 ​​^^遍历中使用边)的同时,使用"coalesce"步骤的正确用法以及通常的附加优点是什么?

除非我误读了它,否则没有任何理由使用coalesce(),因为它在5中使用了,因为它没有第二个参数.当您要获取或创建"或更新"元素时,通常在添加顶点/边的上下文中使用coalesce()-您可以了解有关

在执行has()时最好包括顶点标签,因为这样您就可以显式命名要搜索的键的名称.您在示例中使用了"prop1"-如果"prop1"不是全局唯一键,并且只希望"LABEL1"顶点但"LABEL2"顶点也具有"prop1"值,那么您可能无法获得所需的值.我想如果您使用全局唯一的键名,那么这不是问题,但是我认为,如果您想最大程度地提高Gremlin的可移植性,那么您可能想开始实践,因为我认为那里有一些图系统要求标签的规格.

在将遍历分配给变量后(例如,"t = gV()...")经过几个步骤,然后仅执行一次就足够了,最后,调用"t.iterate()"还是应该这样每次都做?

iterate()是终止步骤.通常,您称其为产生遍历可能产生的任何副作用.一旦被迭代",您就真的不能再调用它了,因为它是无效的,因为迭代是一种单向操作,并且一旦遍历器对象用尽,iterate()就再也没有剩下了.

在脚本的哪一点应该调用"tx.commit()":在多次遍历结束时仅调用一次就足够了吗?

如果您遵循最佳实践,则根本不会致电commit(). Gremlin Server为您管理交易.一个请求(即遍历)基本上是一个事务.唯一需要调用commit()的时间是,如果您选择在会话或非常长时间运行的脚本的上下文中自己管理事务.如果要构建新的应用程序,则应避免使用这些选项中的任何一个,而只需使用

2) What is the purpose, and correct usage, of " __.V() "?

g.V().property("prop1", "prop1_val")
 .as_("a").V().property("prop2", "prop2_val")
 .as_("b").addE("some_relationship")
 .property("prop1_val_weight", 0.1d)
# AND THEN:
 .from_("a").to("b")
# VERSUS: 
 .from_(__.V("a")).to(__.V("b"))

3) What are the differences between using "property" vs. "properties":

g.V().property("prop1", "prop1_val").as_("a")
# VERSUS:
g.V().properties("prop1", "prop1_val").as_("a")
# REST OF THE TRAVERSAL:
 .V().property("prop2", "prop2_val").as_("b")
 .addE("some_relationship")
 .property("prop1_val_weight", 0.1d)
 .from_("a").to("b")

4) What happens when there is no ".to()" vertex/vertices specified, and in this case, also using " __.V() " :

g.V().property("prop1", "prop1_val").as_("a")
 .V().property("prop2", "prop2_val").as_("b")
 .addE("some_relationship").to(__.V()
 .has("prop2", "prop2_val"))

5) What are the reasons for adding " .profile()" at the end of a traversal:

g.V('Alice').as_('v').V('Bob').coalesce(inE('spokeWith')
 .where(outV().as_('v')).addE('spokeWith')
 .property('date', 'xyz').from_('v'))
 .profile()

6) What is the correct usage, and in general the added advantage, of using the "coalesce" step while adding edges, like it's being used in the traversal at 5 ^^ ?

7) And a few general questions:

  • what is the advantage of also looking for the label, e.g. " g.V().has("LABEL1", "prop1", "prop1_val").as_("a") [etc.]"
  • after assigning a traversal to a variable (eg. " t = g.V() ... " in several steps, is it sufficient to then only once, at the end, call "t.iterate()" or should this be done each time?
  • at which point in a script should one call "tx.commit()": is calling it only once, at the end of several traversals, sufficient?

解决方案

1) What is the best order of adding properties to the edge, while creating it

I don't think there is a "best order" operationally speaking, but personally I think it reads better to see the from() and to() immediately follow addE().

2) What is the purpose, and correct usage, of " __.V() "?

You can't use a mid-traversal V() in that fashion. Doing so is basically saying "find me the vertex in the graph with the T.id of "a" which doesn't exist. "a" in your case is a step label that local to the scope of that traversal only.

3) What are the differences between using "property" vs. "properties":

There is a massive difference. property(k,v) is a mutation step which modifies the graph element in the stream with by adding/updating the property key with the specified value. properties(k...) gets the list of properties specified by the provided keys (i.e. a read operation).

4) What happens when there is no ".to()" vertex/vertices specified, and in this case, also using " __.V() "

Why not start up Gremlin Console and see:

gremlin> g.addV().addE('self')
==>e[17][16-self->16]
gremlin> g.addV().as('z').addE('self').property('x','y').from('z').to(V().has('person','name','nobody'))
The provided traverser does not map to a value: v[20]->[TinkerGraphStep(vertex,[~label.eq(person), name.eq(nobody)])]
Type ':help' or ':h' for help.
Display stack trace? [yN]

5) What are the reasons for adding " .profile()" at the end of a traversal:

The same reasons you would profile your code or explain a SQL query - to get more detailed understanding of what that code is doing. Maybe you need to see if an index is being used properly or figure out what step is taking the longest to execute to see if you can better optimize your traversal.

6) What is the correct usage, and in general the added advantage, of using the "coalesce" step while adding edges, like it's being used in the traversal at 5 ^^ ?

Unless I'm misreading it, I don't see any reason to use coalesce() as it is used in 5 as there is no second argument to it. You typically use coalesce() in the context of adding vertices/edges when you want to "get or create" or "upsert" an element - you can read more about that here.

what is the advantage of also looking for the label, e.g. " g.V().has("LABEL1", "prop1", "prop1_val").as_("a") [etc.]"

It's best to include the vertex label when doing a has() as you then explicitly namespace the key you are searching on. You used "prop1" in your example - if "prop1" was not a globally unique key and you only wanted "LABEL1" vertices but "LABEL2" vertices also had "prop1" values then you might not be getting what you want. I suppose that if you use globally unique key names then this isn't a problem but I think that if you want to maximize the portability of your Gremlin you might want to get into the practice as I think there are some graph systems out there that require the specification of the label.

after assigning a traversal to a variable (eg. " t = g.V() ... " in several steps, is it sufficient to then only once, at the end, call "t.iterate()" or should this be done each time?

iterate() is a terminating step. You typically call it to generate any side-effects that the traversal may generate. Once "iterated", you really can't call it again as it will have no effect as iteration is a one way operation and once the traverser objects are exhausted there is nothing left to iterate() again.

at which point in a script should one call "tx.commit()": is calling it only once, at the end of several traversals, sufficient?

If you are following best practices you aren't calling commit() at all. Gremlin Server manages your transactions for you. One request (i.e. traversal) is basically one transaction. The only time you ever need to call commit() is if you choose to manage transactions yourself in the context of a session or a really long run script. If you are building a new application you should avoid either of those options and simply utilize bytecode-based traversals.

这篇关于了解使用Gremlin-Python添加边缘的不同方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆