JanusGraph 入门


Getting Started
http://docs.janusgraph.org/latest/getting-started.html

JanusGraph 第三章 入门

本节中的例子展示了如何使用JanusGraph检索诸神关系图. 关系图如下图所示.抽象数据模型使用大家都熟知的Property Graph Model ,而且这个例子描述了罗马诸神中的人物和他们所在位置之间的联系.

Figure 3.1. 诸神关系图
JanusGraph 入门_第1张图片
虚拟元素 意义

粗体的关键字

图的索引

粗体加星的关键字

图的索引, 必须唯一

下划线的关键字

顶点中心索引

空心箭头的边

功能或者唯一的边(不能重复)

尾巴带横线的边

单向的边, 只能按照一个方向进行访问

3.1 下载JanusGraph和运行Gremlin命令行

JanusGraph的下载地址可以从最新的发布页面获得. 下载后解压, 就可以找到Gremlin命令行. Gremlin命令行是一种REPL, 与标准Groovy命令行的的微小区别, JanusGraph仅仅是一种预安装和预加载的包.
用户可以通过从中心仓库下载JanusGraph包, 在Gremlin命令行中安装后激活JanusGraph.在下列的例子中, 确保下载janusgraph.zip文件, 并解压了这个压缩包

Important

JanusGraph需要Java8(标准版本) 推荐使用Oracle Java8. JanusGraph 的脚本需要$JAVA_HOME环境变量指向JRE或者JDK的安装目录

$ unzip janusgraph-0.2.0-hadoop2.zip
Archive:  janusgraph-0.2.0-hadoop2.zip
  creating: janusgraph-0.2.0-hadoop2/
...
$ cd janusgraph-0.2.0-hadoop2
$ bin/gremlin.sh

         \,,,/
         (o o)
-----oOOo-(3)-oOOo-----
09:12:24 INFO  org.apache.tinkerpop.gremlin.hadoop.structure.HadoopGraph  - HADOOP_GREMLIN_LIBS is set to: /usr/local/janusgraph/lib
plugin activated: tinkerpop.hadoop
plugin activated: janusgraph.imports
gremlin>

Gremlin命令行使用Groovy翻译用户输入的命令. Groovy是java的一个扩展, 设计了许多简短标记, 可以让交互性编程语言更容易使用. 同样Gremlin-Groovy是Groovy的一个扩展, 让图的遍历更加方便.以下基本例子展示了JanusGraph使用数字, 字符串和map的基本方法. 教程的其他部分要讨论图特有的结构.

gremlin> 100-10
==>90
gremlin> "JanusGraph:" + " The Rise of Big Graph Data"
==>JanusGraph: The Rise of Big Graph Data
gremlin> [name:'aurelius', vocation:['philosopher', 'emperor']]
==>name=aurelius
==>vocation=[philosopher, emperor]

Tip

Refer to Apache TinkerPop, SQL2Gremlin, and Gremlin Recipes for more information about using Gremlin.

3.2 读取诸神关系图到JanusGraph

以下例子创建了JanusGraph的实例, 后加载了诸神关系图. JanusGraphFactory提供一系列静态读取配置参数方法, 每个方法会根据配置参数的不同, 返回一个对应的实例. 这里的示例使用BerkeleyDB存储和Elasticsearch索引, 通过GraphOfTheGodsFactory类加载诸神关系图. 本章没有讨论配置的详细内容, 如果要查看存储、索引和配置的详细信息, 请跳到对应章节

gremlin> graph = JanusGraphFactory.open('conf/janusgraph-berkeleyje-es.properties')
==>standardjanusgraph[berkeleyje:../db/berkeley]
gremlin> GraphOfTheGodsFactory.load(graph)
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[standardjanusgraph[berkeleyje:../db/berkeley], standard]

JanusGraphFactory.open() 和 GraphOfTheGodsFactory.load()创建了一个图对象, 主要分3步
1. 为图创建了一系列全局, 顶点中心索引
2. 为图添加了顶点, 和顶点的属性
3. 为图添加了边, 和边的属性

想要看更详细的信息, 可以查看对应 源码

这里使用的是JanusGraph/Cassandra, 确定加载了对应的配置文件conf/janusgraph-cassandra-es.properties, 执行了GraphOfTheGodsFactory.load()方法, 若使用HBase和es, 请读取conf/janusgraph-hbase-es.properties配置

gremlin> graph = JanusGraphFactory.open('conf/janusgraph-cassandra-es.properties')
==>standardjanusgraph[cassandrathrift:[127.0.0.1]]
gremlin> GraphOfTheGodsFactory.load(graph)
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[standardjanusgraph[cassandrathrift:[127.0.0.1]], standard]

你可能不需要使用索引, 那就读取下边几种conf/janusgraph-cassandra.properties, conf/janusgraph-berkeleyje.properties, or conf/janusgraph-hbase.properties. 另一个方法GraphOfTheGodsFactory.loadWithoutMixedIndex()来加载数据

gremlin> graph = JanusGraphFactory.open('conf/janusgraph-cassandra.properties')
==>standardjanusgraph[cassandrathrift:[127.0.0.1]]
gremlin> GraphOfTheGodsFactory.loadWithoutMixedIndex(graph, true)
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[standardjanusgraph[cassandrathrift:[127.0.0.1]], standard]


3.3. 全局索引

访问图数据库中的数据, 首先是根据图的索引定位到切入点. 切入点是一个元素(或者一组元素), 例如:一个顶点或者一个边. Gremlin路径描述了如何通过图的结构, 从切入点元素访问到其他元素.
根据图, name属性的索引是唯一的, 可以通过这种方法访问克罗诺斯(Saturn)顶点. 也就可以获得该顶点的属性map, 克罗诺斯顶点name是克罗诺斯, age是10000, type是巨人. 克罗诺斯的孙子是谁? 结果是海格力斯.

gremlin> saturn = g.V().has('name', 'saturn').next()
==>v[256]
gremlin> g.V(saturn).valueMap()
==>[name:[saturn], age:[10000]]
gremlin> g.V(saturn).in('father').in('father').values('name')
==>hercules

坐标属性也属于图的索引. 坐标是边的属性. 所以, JanusGraph可以把边放到索引中. 你可能会查询距离Athens(维度:37.97, 经度:23.72)50公里内发生的事情. 查出那个顶点是包含在其中的.

gremlin> g.E().has('place', geoWithin(Geoshape.circle(37.97, 23.72, 50)))
==>e[a9x-co8-9hx-39s][16424-battled->4240]
==>e[9vp-co8-9hx-9ns][16424-battled->12520]
gremlin> g.E().has('place', geoWithin(Geoshape.circle(37.97, 23.72, 50))).as('source').inV().as('god2').select('source').outV().as('god1').select('god1', 'god2').by('name')
==>[god1:hercules, god2:hydra]
==>[god1:hercules, god2:nemean]

图索引是JanusGraph索引结构中的一种. JanusGraph要访问全部顶点或者全部边, 图的索引会自动匹配
JanusGraph中另一种索引被称为顶点中心索引. 顶点中心索引用来加速图的内部访问. 稍后做解释

3.3.1 访问图的例子

海格力斯是朱庇特和埃尔克莫尼的儿子, 拥有超过常人的力量. 海格力斯父亲是神,母亲是人类, 所以他是半人半神,
Juno是朱庇特的妻子, 对他的不忠极其气愤. 为了报复, 她蒙蔽了朱庇特, 并让朱庇特杀了他的妻子和孩子.为了补偿, 海格力斯被特尔非神谕安排服役于Eurystheus.

上一节, 克罗诺斯的孙子是海格力斯, 这可以使用循环, 从克罗诺斯沿着两次父亲的路径, 可以找到海格力斯

gremlin> hercules = g.V(saturn).repeat(__.in('father')).times(2).next()
==>v[1536]

为证明海格力斯是半人半神. 需要检查他的父母身世. 可以从海格力斯访问到他的父母节点. 可以找出父母的类型是神和人类.

gremlin> g.V(hercules).out('father', 'mother')
==>v[1024]
==>v[1792]
gremlin> g.V(hercules).out('father', 'mother').values('name')
==>jupiter
==>alcmene
gremlin> g.V(hercules).out('father', 'mother').label()
==>god
==>human
gremlin> hercules.label()
==>demigod

例子展示了罗马诸神的基因关系. Property Graph Model已经足够处理事物的多个类型和关系. 在上一节, 海格力斯在Athens附近打了两次仗, 通过访问battled边可以找到这些事件.

gremlin> g.V(hercules).out('battled')
==>v[2304]
==>v[2560]
==>v[2816]
gremlin> g.V(hercules).out('battled').valueMap()
==>[name:[nemean]]
==>[name:[hydra]]
==>[name:[cerberus]]
gremlin> g.V(hercules).outE('battled').has('time', gt(1)).inV().values('name')
==>cerberus
==>hydra

battled边的time属性会被顶点中心索引管理. 对指定的边进行查找或过滤, 要比扫描全部的边再过滤要更快.JanusGraph可以自动使用顶点中心索引.

gremlin> g.V(hercules).outE('battled').has('time', gt(1)).inV().values('name').toString()
==>[GraphStep([v[24744]],vertex), VertexStep(OUT,[battled],edge), HasStep([time.gt(1)]), EdgeVertexStep(IN), PropertiesStep([name],value)]

3.3.2 更复杂的例子

普鲁托住在冥界. 他跟明海格力的联系是, 明海格力打过他的宠物.尽管这样, 明海格力是他的侄子, 普鲁托会怎样处理对他侄子的无礼.
Gremlin提供更多的例子. 每一个实例的解释


gremlin> pluto = g.V().has('name', 'pluto').next()
==>v[2048]
gremlin> // who are pluto's cohabitants?
gremlin> g.V(pluto).out('lives').in('lives').values('name')
==>pluto
==>cerberus
gremlin> // pluto can't be his own cohabitant
gremlin> g.V(pluto).out('lives').in('lives').where(is(neq(pluto))).values('name')
==>cerberus
gremlin> g.V(pluto).as('x').out('lives').in('lives').where(neq('x')).values('name')
==>cerberus

3.3.2.2. 普鲁托的兄弟们

gremlin> // where do pluto's brothers live?
gremlin> g.V(pluto).out('brother').out('lives').values('name')
==>sky
==>sea
gremlin> // which brother lives in which place?
gremlin> g.V(pluto).out('brother').as('god').out('lives').as('place').select('god', 'place')
==>[god:v[1024], place:v[512]]
==>[god:v[1280], place:v[768]]
gremlin> // what is the name of the brother and the name of the place?
gremlin> g.V(pluto).out('brother').as('god').out('lives').as('place').select('god', 'place').by('name')
==>[god:jupiter, place:sky]
==>[god:neptune, place:sea]


普鲁托不畏惧死亡, 所以他住在冥界. 
相反, 他的兄弟们选择住在充满爱的地方.


gremlin> g.V(pluto).outE('lives').values('reason')
==>no fear of death
gremlin> g.E().has('reason', textContains('loves'))
==>e[6xs-sg-m51-e8][1024-lives->512]
==>e[70g-zk-m51-lc][1280-lives->768]
gremlin> g.E().has('reason', textContains('loves')).as('source').values('reason').as('reason').select('source').outV().values('name').as('god').select('source').inV().values('name').as('thing').select('god', 'reason', 'thing')
==>[god:neptune, reason:loves waves, thing:sea]
==>[god:jupiter, reason:loves fresh breezes, thing:sky]

你可能感兴趣的:(JanusGraph 入门)