图计算介绍

概述

图(graph)是一种由顶点和边组成的数据结构。在计算机中建模的图,一般包含标记(label)和键值属性(key/value)。这种图的结构就叫属性图(property graph)。下图是一个称之为“TinkerPop Classic”的属性图示例。

图计算介绍_第1张图片
TinkerPop Modern

TinkerPop3是TinkerPop图计算框架的第三个版本(incarnation)。类似于一般的计算过程,图计算可分为结构(structure,比如图graph)和处理(process,比如遍历traversal)两部分。图的结构指的是由顶点/边/属性等拓扑学概念所定义的数据模型。图的处理是分析图结构的手段或方法。

图计算介绍_第2张图片
Graph Computing

TinkerPop3图处理API的主要组件

  • TraversalSource:针对特定图的遍历产生器(generator),DSL,执行引擎。
    1.Traversal:一个功能性数据流处理过程,可将S类型的对象转换成E类型的对象
    2.GraphTraversal:面向原始图(raw graph)语义的遍历DSL

  • GraphComputer:一个在多机器集群上后台运行的、并行的、分布式的处理图的系统
    1.VertexProgram:通过消息交互,以逻辑上并行的方式,在所有顶点上执行的代码
    2.MapReduce:用于并行分析图中所有节点,并得到单一的归纳(reduced)结果的一组计算指令

图的结构(Graph Structure)

一个图的结构是在它的顶点,边,属性之中,显示地相互引用所形成的拓扑。一个顶点有其关联的边。一个顶点与另一个顶点共享一条边,那么它们就是相邻顶点。一个属性必定附属到一个元素上,而一个元素一般会有一个属性集合。一个属性是一个key/value对,其中key是一个字符串。TinkerPop3的图结构API提供了创建一个图结构所必要那些方法。

Graph graph = TinkerGraph.open(); (1)
Vertex marko = graph.addVertex(T.label, "person", T.id, 1, "name", "marko", "age", 29); (2)
Vertex vadas = graph.addVertex(T.label, "person", T.id, 2, "name", "vadas", "age", 27);
Vertex lop = graph.addVertex(T.label, "software", T.id, 3, "name", "lop", "lang", "java");
Vertex josh = graph.addVertex(T.label, "person", T.id, 4, "name", "josh", "age", 32);
Vertex ripple = graph.addVertex(T.label, "software", T.id, 5, "name", "ripple", "lang", "java");
Vertex peter = graph.addVertex(T.label, "person", T.id, 6, "name", "peter", "age", 35);
marko.addEdge("knows", vadas, T.id, 7, "weight", 0.5f); (3)
marko.addEdge("knows", josh, T.id, 8, "weight", 1.0f);
marko.addEdge("created", lop, T.id, 9, "weight", 0.4f);
josh.addEdge("created", ripple, T.id, 10, "weight", 1.0f);
josh.addEdge("created", lop, T.id, 11, "weight", 0.4f);
peter.addEdge("created", lop, T.id, 12, "weight", 0.2f);

图的变形(Mutating the Graph)

Graph graph = TinkerGraph.open();
// add a software vertex with a name property
Vertex gremlin = graph.addVertex(T.label, "software",
                             "name", "gremlin"); (1)
// only one vertex should exist
assert(IteratorUtils.count(graph.vertices()) == 1)
// no edges should exist as none have been created
assert(IteratorUtils.count(graph.edges()) == 0)
// add a new property
gremlin.property("created",2009) (2)
// add a new software vertex to the graph
Vertex blueprints = graph.addVertex(T.label, "software",
                                "name", "blueprints"); (3)
// connect gremlin to blueprints via a dependsOn-edge
gremlin.addEdge("dependsOn",blueprints); (4)
// now there are two vertices and one edge
assert(IteratorUtils.count(graph.vertices()) == 2)
assert(IteratorUtils.count(graph.edges()) == 1)
// add a property to blueprints
blueprints.property("created",2010) (5)
// remove that property
blueprints.property("created").remove() (6)
// connect gremlin to blueprints via encapsulates
gremlin.addEdge("encapsulates",blueprints) (7)
assert(IteratorUtils.count(graph.vertices()) == 2)
assert(IteratorUtils.count(graph.edges()) == 2)
// removing a vertex removes all its incident edges as well
blueprints.remove() (8)
gremlin.remove() (9)
// the graph is now empty
assert(IteratorUtils.count(graph.vertices()) == 0)
assert(IteratorUtils.count(graph.edges()) == 0)
// tada!
图计算介绍_第3张图片

图的处理(Graph Process)

处理图的主要方法是图的遍历。一次遍历指的是,根据图数据结构中的指涉结构(referential structure),按一定算法步骤来走遍图中指定的元素。举例说明

What software does vertex 1’s friends work on?
1.Start at vertex 1.
2.Walk the incident knows-edges to the respective adjacent friend vertices of 1.
3.Move from those friend-vertices to software-vertices via created-edges.
4.Finally, select the name-property value of the current software-vertices.

GraphTraversalSource继承自TraversalSource,提供的了两种遍历的方法。

  1. GraphTraversalSource.V(Object... ids)
  2. GraphTraversalSource.E(Object... ids)

v()E()的返回类型为GraphTraversalGraphTraversal支持函数式编程(function composition)。GraphTraversal的每一个方法称为一步(step),每一步会以五种常用方式中的一种来转调(modulate)上一步的结果。

  1. map:将一个对象转换成另一个对象(S -> E)
  2. flatMap:将一个对象转换成另一些对象的迭代器(S -> E*)
  3. filter:允许或不允许遍历器进行下一步的处理(S → S ∪ ∅).
  4. sideEffect:不改变当对象,但会产生计算副作用(S ↬ S)
  5. branch:将对象送到任务的分支中(S → { S1 → E, …, Sn → E } → E*)

示例

$ bin/gremlin.sh

         \,,,/
         (o o)
-----oOOo-(3)-oOOo-----
gremlin> graph = TinkerFactory.createModern() (1)
==>tinkergraph[vertices:6 edges:6]
gremlin> g = graph.traversal(standard())        (2)
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().has('name','marko').out('knows').values('name') (3)
==>vadas
==>josh
gremlin> marko = g.V().has('name','marko').next() //(1)
==>v[1]
gremlin> g.V(marko).out('knows') //(2)
==>v[2]
==>v[4]
gremlin> g.V(marko).out('knows').values('name') //(3)
==>vadas
==>josh
图计算介绍_第4张图片

遍历器(Traverser)

图计算介绍_第5张图片

示例path()

gremlin> g.V(marko).out('knows').values('name').path()
==>[v[1], v[2], vadas]
==>[v[1], v[4], josh]

示例repeat()

gremlin> g.V(marko).repeat(out()).times(2).values('name')
==>ripple
==>lop

关于Gremlin语言变体

  • Gremlin-Groovy
  • Gremlin-Scala
  • Gremlin-JavaScript
  • Gremlin-Clojure

供应商集成

TinkerPop是一个由各种互相协作组件组成的框架。核心API(core API)定义了什么是图,顶点,边等。供应商必须实现核心API。一旦实现,那么用户就能使用Gremlin遍历语言了。然而,供应商还可以更进一步提供特殊化的TraversalStrategy优化策略,以便供应商在运行时检查Gremlin查询,同时优化它们的执行(比如使用索引查询,步骤顺序优化)。如果供应商的图系统是图处理器(graph processor,提供OLAP能力),那么供应商可实现GraphComputerAPI。这些API定义了如何在工作者(worker,比如线程或机器)进行消息或遍历器的通讯。
Gremlin语言将图以顶点和边进行转义,它是一种基于图的领域专属语言。用户可以定义属于自己的高阶领域专属语言去进行图处理。Gremlin服务器可用于与TinkerPop使能的图系统进行可靠通讯。

图计算介绍_第6张图片

你可能感兴趣的:(图计算介绍)