简体   繁体   English

了解使用Gremlin-Python添加边缘的不同方法

[英]Understanding different methods for adding edges with Gremlin-Python

I'm trying to understand the differences in methods, and the best syntax for adding edges (between existing vertices) in Gremlin-Python. 我试图了解方法的差异,以及在Gremlin-Python中添加边缘(在现有顶点之间)的最佳语法。

Having read several posts here on SO, I've subdivided some different approaches I found into a few questions. 在阅读了SO的几篇文章之后,我将发现的一些不同方法细分为几个问题。

Many thanks for any feedback in advance! 非常感谢您的任何提前反馈!

1) What is the best order of adding properties to the edge, while creating it: which one of these would be the better option (in case there is any significant difference at all)? 1)在创建边缘时,向边缘添加属性的最佳顺序是什么:哪一种是更好的选择(以防万一有任何显着差异)?

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) What is the purpose, and correct usage, of " __.V() " ? 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) What are the differences between using "property" vs. "properties" : 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) What happens when there is no ".to()" vertex/vertices specified , and in this case, also using " __.V() " : 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) What are the reasons for adding " .profile()" at the end of a traversal: 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) 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 ^^ ? 6)在添加边(例如在5 ​​^^遍历中使用边)的同时,使用“ coalesce”步骤的正确用法以及通常的附加优点是什么?

7) And a few general questions : 7)和一些一般性问题

  • what is the advantage of also looking for the label, eg " gV().has("LABEL1", "prop1", "prop1_val").as_("a") [etc.]" 还寻找标签的好处是什么,例如“ gV()。has(“ LABEL1”,“ prop1”,“ prop1_val”)。as _(“ a”)[etc.]“
  • after assigning a traversal to a variable (eg. " t = gV() ... " in several steps, is it sufficient to then only once, at the end, call "t.iterate()" or should this be done each time? 在将遍历分配给变量后(例如,“ t = gV()...”)经过多个步骤后,仅再执行一次就足够了,最后,调用“ t.iterate()”还是应该分别进行一次时间?
  • at which point in a script should one call "tx.commit()": is calling it only once, at the end of several traversals, sufficient? 在脚本的哪一点应该调用“ tx.commit()”:在多次遍历结束时仅调用一次就足够了吗?

1) What is the best order of adding properties to the edge, while creating it 1)在创建边缘时向边缘添加属性的最佳顺序是什么

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() . 从操作上讲,我认为没有“最佳顺序”,但是就我个人而言,最好将addE()from()to()紧随addE()

2) What is the purpose, and correct usage, of " __.V() "? 2)“ __。V()”的目的和正确用法是什么?

You can't use a mid-traversal V() in that fashion. 您不能以这种方式使用中间遍历V() 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. 这样做基本上是说“在T.id中找到不存在的图的顶点”,在您的情况下,“ a”是仅位于该遍历范围局部的步骤标签。

3) What are the differences between using "property" vs. "properties": 3)使用“属性”与“属性”有什么区别:

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. property(k,v)是一个变异步骤,通过添加/更新具有指定值的属性键来修改流中的图形元素。 properties(k...) gets the list of properties specified by the provided keys (ie a read operation). properties(k...)获取由提供的键指定的属性列表(即读取操作)。

4) What happens when there is no ".to()" vertex/vertices specified, and in this case, also using " __.V() " 4)如果未指定“ .to()”个顶点/顶点,并且在这种情况下也使用“ __。V()”,会发生什么情况?

Why not start up Gremlin Console and see: 为什么不启动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) What are the reasons for adding " .profile()" at the end of a traversal: 5)在遍历末尾添加“ .profile()”的原因是什么:

The same reasons you would profile your code or explain a SQL query - to get more detailed understanding of what that code is doing. 出于相同原因,您需要分析代码或解释SQL查询-以便更详细地了解该代码在做什么。 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 ^^ ? 6)在添加边(例如在5 ​​^^遍历中使用边)的同时,使用“ coalesce”步骤的正确用法以及通常的附加优点是什么?

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. 除非我读错了它,否则我看不出有任何理由使用coalesce()因为它在5中使用,因为它没有第二个参数。 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 . 当您要“获取或创建”或“增补”元素时,通常在添加顶点/边的上下文中使用coalesce()此处可以了解更多信息。

what is the advantage of also looking for the label, eg " gV().has("LABEL1", "prop1", "prop1_val").as_("a") [etc.]" 还寻找标签的好处是什么,例如“ gV()。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. 最好在执行has()时包括顶点标签,然后在要搜索的键上显式命名空间。 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. 您在示例中使用了“ prop1”-如果“ prop1”不是全局唯一键,并且只希望“ LABEL1”顶点但“ LABEL2”顶点也具有“ prop1”值,那么您可能无法获得所需的值。 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. 我想如果您使用全局唯一的键名,那么这不是问题,但是我认为,如果您想最大程度地提高Gremlin的可移植性,那么您可能想开始实践,因为我认为那里有一些图系统要求标签的规格。

after assigning a traversal to a variable (eg. " t = gV() ... " in several steps, is it sufficient to then only once, at the end, call "t.iterate()" or should this be done each time? 在将遍历分配给变量后(例如,“ t = gV()...”)经过多个步骤后,仅再执行一次就足够了,最后,调用“ t.iterate()”还是应该分别进行一次时间?

iterate() is a terminating step. iterate()是终止步骤。 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. 一旦被“迭代”,您将无法再调用它,因为迭代是一种单向操作,并且遍历器对象耗尽后,就再也没有可以iterate()对象了。

at which point in a script should one call "tx.commit()": is calling it only once, at the end of several traversals, sufficient? 在脚本的哪一点应该调用“ tx.commit()”:在多次遍历结束时仅调用一次就足够了吗?

If you are following best practices you aren't calling commit() at all. 如果您遵循最佳实践,则根本不会调用commit() Gremlin Server manages your transactions for you. Gremlin Server为您管理交易。 One request (ie 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. 唯一需要调用commit()是,如果您选择在会话或非常长时间运行的脚本的上下文中自己管理事务。 If you are building a new application you should avoid either of those options and simply utilize bytecode-based traversals . 如果要构建新的应用程序,则应避免使用这些选项中的任何一个,而应仅使用基于字节码的遍历

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM