在 TinkerPop 中,图元素(例如顶点、边、顶点属性)经常会经历一个“分离”的过程。从远程源返回图形元素的 Gremlin 遍历会经历这个过程,在这些情况下,通常与“引用”分离。引用提供了足够的信息来重新附加到远程图。对于重新连接的过程,它只需要id
和label
。因此,不会返回属性。Gremlin 支持的所有语言都是一样的,而不仅仅是 Python(不过,我会在最后的最后说明中与此声明有点矛盾)。
专门针对 Gremlin 语言变体(如 Python)而言,Gremlin 的这些实现没有完整的 Gremlin 虚拟机来处理遍历,并且从来没有打算在 Python 端构建完整的图形结构 - 只有带有引用的图形元素才能匹配从远程来源返回。这也减少了 Python 端需要维护的代码量,因为 TinkerPop 可以依赖于所有编程语言中存在的标准原语等Dictionary
。List
抛开技术历史不谈,引用的回归力用于根据最佳实践编写更好的 Gremlin。用户应该在 Gremlin 遍历中准确指定他们想要的数据。而不是:
g.V().hasLabel('customer')
你更喜欢:
g.V().hasLabel('customer').valueMap(true,'name')
或在 3.4.4 中:
g.V().hasLabel('customer').elementMap('name')
它返回的嵌套结构比valueMap()
. elementMap()
非常适用于边缘,并且可以替代更复杂的方法,通过project()
从问题中的边缘获取您请求的数据:
gremlin> g.V().has('person','name','marko').elementMap()
==>[id:1,label:person,name:marko,age:29]
gremlin> g.V().has('person','name','marko').elementMap('name')
==>[id:1,label:person,name:marko]
gremlin> g.V().has('person','name','marko').properties('name').elementMap()
==>[id:0,key:name,value:marko]
gremlin> g.E(11).elementMap()
==>[id:11,label:created,IN:[id:3,label:software],OUT:[id:4,label:person],weight:0.4]
在你可能不会做的 SQL 中,这确实没有什么不同:
SELECT * FROM customer
但反而:
SELECT name FROM customer
返回引用并强制用户更明确地了解他们返回的内容也解决了多/元属性的一个巨大问题。如果用户返回顶点并无意中返回了一个“胖”顶点(例如,一个具有 100 万个属性的顶点),它将对尝试返回该顶点的服务器产生重大影响。通过脱离参考,用户不会陷入困境。
尽管如此,从 3.4.3 开始,分离仍然存在一些不一致的地方,在 Java 中的某些情况下,除了引用分离之外,分离还有其他工作方式。TinkerPop 一直试图在这种方法中变得完全一致,但一直在尝试以一种不会破坏现有发布行中现有代码的方式来做到这一点。这可能不是您要寻找的答案,但至少它有助于解释为什么事情是这样的一些推理和历史。