(2)JanusGraph学习----入门
安装:
1.从github上下载相应版本的安装包:https://github.com/JanusGraph/janusgraph/releases
2.需要jdk8环境。Oracle Java 8 is recommended.
3.解压:
> unzip janusgraph-0.3.1-hadoop2.zip
4.打开命令行:
> cd janusgraph-0.3.1-hadoop2
> bin/gremlin.sh
5.测试:
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]
演示demo:
下面的示例将打开JanusGraph图形实例,并加载上图所示的神之图数据集。 JanusGraphFactory
提供了一组静态open
方法,每个方法都将配置作为参数并返回图形实例。本教程调用
BerkeleyDB存储后端和Elasticsearch索引后端的配置上公开方法中的一个方法,然后使用帮助程序类GraphOfTheGodsFactory加载神之图。本节将跳过配置详细信息,但有关存储后端,索引后端及其配置的其他信息,后续会详细讲解
1.加载神之图谱进入 JanusGraph
首先启动自带的ES环境:./bin/janusgraph.sh start (这个命令启动 Cassandra, ES, and Gremlin-Server 三个进程,注意ES不能用root用户启动,需要切换其他用户)
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()
方法做了如下操作去优先返回新的图结构:
在图形上创建全局和以节点为中心的索引的集合。
将所有节点及其属性添加到图中。
将所有边及其属性添加到图中。
2.全局图索引
在图数据库中访问数据的经典模式是首先使用图索引定位到图的进入点。进入点是一个元素(或者元素集合)-比如:一个节点或者边。从这个进入元素,一个gremlin路径描述如何通过明确的图结构去遍历到图中的其他元素。
鉴于在name属性上有索引,Saturn节点可以被返回。然后map属性(比如:这个saturn的k/v键值对)可以被检查。如图所示,saturn节点有一个name是“saturn”,一个age是10000,一个type是“titan”。这个saturn的孙子可以被一个遍历表达:“谁是saturn的孙子?”而返回,结果是Hercules。
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
place属性也在图索引中。这个属性是一个边属性,因此,JG可以在图索引中索引边。可以去查询神之图中发生在雅典周围50km范围内的所有事件。然后,基于查询信息,找出哪些节点是包含在事件中。
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自动选择图形索引来回答要求满足一个或多个约束的所有顶点(g.V
)或所有边(g.E)。JanusGraph索引的第二个方面称为以节点为中心的索引。以节点为中心的索引用于加速图中的遍历。以节点为中心的索引将在后面描述。
2.1图遍历例子
Hercules,是Jupiter and Alcmene的儿子。Hercules 是一个半神,因为Jupiter是神,Alcmene是人。Juno是导致Jupiter的妻子,痛恨小三,所以为了报复,她弄瞎了Hercules,导致Hercules杀掉了他的妻子和儿子。
在之前的章节中,演示了saturn的孙子是Hercules。可以用loop循环来表达。本质上,Hercules是从saturn的in('father')
路径出去的二度节点。
gremlin>hercule=g.V(saturn).repeat(__.in('father')).times(2).next()
==>v[1536]
Hercules是一个半神。为了证明Hercules是半人半神,他的父母的起源
必须被检查。
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
在上面的章节中,发现Hercules被卷入在雅典附近的两场战争。可以通过遍历
Hercules节点的向外的战斗的边来探索这些事件
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是被节点中心索引。battled通过一个在time上的约束/过滤 比 对所有边做一个线性扫描过滤更快。JG足够智能的会自动优先使用节点中心索引。toString()表达式可以分解成独立的步骤。
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)]
2.2 更复杂的图遍历例子
2.2.1 pluto的同居者
在Tartarus的深处生活着Pluto。他和Hercules的关系因为-Hercules和他的宠物Cerberus战斗而变得紧张。但是,Hercules是他的侄子—他如何能够让Hercules为他的傲慢付出代价呢?
gremlin>pluto=g.V().has('name', 'pluto').next()
==>v[2048]
gremlin> //pluto的同居者是谁?
gremlin>g.V(pluto).out('lives').in('lives').values('name')
==>pluto
==>cerberus
gremlin> // pluto 不能是自己的同居者
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
2.2.2 pluto的兄弟
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]
后,Pluto生活在Tartarus因为他不关心死亡。另一方面,他的兄弟们根据他们对这些地方某些品质的喜爱来选择他们的位置。
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]
相关文章