jansusgraph是一款分布式开源图数据库。
JanusGraph Server
使用默认的数据库及搜索引擎配置:bin/janusgraph.sh start
自定义存储及搜索引擎:bin/gremlin-server.sh ./conf/gremlin-server/gremlin-server.yaml
gremlin-server.yaml内容:
1 | host: localhost |
发送http请求1
2
3
4
5
6
7
8
9
10
11
12
13
14POST HTTP/1.1
Host: localhost:8182
Content-Type: application/json
User-Agent: PostmanRuntime/7.19.0
Accept: */*
Cache-Control: no-cache
Postman-Token: c8c2454d-8daa-4ac4-ad4c-1d9ad784a6bb,c6e81a95-2862-4cfb-a8ef-3cbcfa8c482c
Host: 172.16.21.46:8182
Accept-Encoding: gzip, deflate
Content-Length: 36
Connection: keep-alive
cache-control: no-cache
{"gremlin": "g.V().limit(1).next()"}
socket-janusgraph-hbase-server.properties内容:
1 | gremlin.graph=org.janusgraph.core.JanusGraphFactory |
还有权限认证功能 见 官方文档
Gremlin
终端连接远程数据库
1 | :remote connect tinkerpop.server conf/remote.yaml |
remote.yaml :
1 | hosts: [localhost] |
基础语句
graph = JanusGraphFactory.open('conf/gremlin-server/socket-janusgraph-hbase-server.properties')
打开数据库连接g=graph.traversal()
的到实列V()
:查询顶点,一般作为图查询的第1步,后面可以续接的语句种类繁多。例,g.V(),g.V('v_id')
,查询所有点和特定点;E()
:查询边,一般作为图查询的第1步,后面可以续接的语句种类繁多;id()
:获取顶点、边的id。例:g.V().id()
,查询所有顶点的id;label()
:获取顶点、边的 label。例:g.V().label()
,可查询所有顶点的label。key() / values()
:获取属性的key/value的值。properties()
:获取顶点、边的属性;可以和 key()、value()搭配使用,以获取属性的名称或值。例:g.V().properties('name')
,查询所有顶点的 name 属性;valueMap()
:获取顶点、边的属性,以Map的形式体现,和properties()
比较像;values()
:获取顶点、边的属性值。例,g.V().values()
等于g.V().properties().value()
遍历(以定点为基础)
out(label)
:根据指定的 Edge Label 来访问顶点的 OUT 方向邻接点(可以是零个 Edge Label,代表所有类型边;也可以一个或多个 Edge Label,代表任意给定 Edge Label 的边,下同);in(label)
:根据指定的 Edge Label 来访问顶点的 IN 方向邻接点;both(label)
:根据指定的 Edge Label 来访问顶点的双向邻接点;outE(label)
: 根据指定的 Edge Label 来访问顶点的 OUT 方向邻接边;inE(label)
:根据指定的 Edge Label 来访问顶点的 IN 方向邻接边;bothE(label)
:根据指定的 Edge Label 来访问顶点的双向邻接边;
遍历(以边为基础)
outV()
:访问边的出顶点,出顶点是指边的起始顶点;inV()
:访问边的入顶点,入顶点是指边的目标顶点,也就是箭头指向的顶点;bothV()
:访问边的双向顶点;otherV()
:访问边的伙伴顶点,即相对于基准顶点而言的另一端的顶点;
过滤
has(key,value)
: 通过属性的名字和值来过滤顶点或边;has(label, key, value)
: 通过label和属性的名字和值过滤顶点和边;has(key,predicate)
: 通过对指定属性用条件过滤顶点和边,例:g.V().has('age', gt(20))
,可得到年龄大于20的顶点;hasLabel(labels…)
: 通过 label 来过滤顶点或边,满足label列表中一个即可通过;hasId(ids…)
: 通过 id 来过滤顶点或者边,满足id列表中的一个即可通过;hasKey(keys…)
: 通过 properties 中的若干 key 过滤顶点或边;hasValue(values…)
: 通过 properties 中的若干 value 过滤顶点或边;has(key)
: properties 中存在 key 这个属性则通过,等价于hasKey(key);hasNot(key)
: 和 has(key) 相反;
分支(if-else)
choose(predicate,true,false)
:判断第一个参数的条件,满足走true分支,不满足走false分支可以与optional()
搭配使用。列子:1
2
3
4
5
6
7
8g.V().hasLabel('person').
choose(values('age').is(lte(30)),
__.in(),
__.out()).values('name')
g.V().hasLabel('person').
choose(values('age')).
option(27, __.in()).
option(32, __.out()).values('name')
循环
repeat()
:指定要重复执行的语句;times()
: 指定要重复执行的次数,如执行3次;until()
:指定循环终止的条件,如一直找到某个名字的朋友为止;loops()
:当前循环的次数,可用于控制最大循环次数等,如最多执行3次。repeat()
和until()
的位置不同,决定了不同的循环效果:repeat()
+until()
:等同 do-while;until()
+repeat()
:等同 while-do
1 | g.V(1) |
Match
匹配数据类似neo4j的match 和as()配合使用
1 | g.V().match( |
project
通过by来进行分支运算
1 | g.V().groupCount().by(label()).unfold().project('k','v').by(map{it->it.get().getKey()}).by(map{it->it.get().getValue()}).order().by(select('v')) |
路径
path()
当前遍历过的路径simplePath()
过滤掉路径中含有环路的对象cyclicPath()
过滤掉路径中不含有环路的对象shortestPath()
最短路径1
g.V().shortestPath().with(ShortestPath.edges, Direction.IN).with(ShortestPath.target, __.has('name','josh'))
统计
sum()
:将 traversal 中的所有的数字求和;max()
:对 traversal 中的所有的数字求最大值;min()
:对 traversal 中的所有的数字求最小值;mean()
:将 traversal 中的所有的数字求均值;count()
:统计 traversal 中 item 总数。
or
这个也是一个过滤语句
1 | g.V().or(out().has('test','test'),in().has('test','test')) |
注意这里返回的是 满足or 里面任一条件的 节点,而不是返回in或者out之后的节点 和下面的语句等价
1 | g.V().where(out().has('test','test').or().in().has('test','test')) |
and,not 和这个类似
union
联合多个结果 比如需要查 某个节点的 in() 和out()节点
1 | g.V().union(__.in(),out()) |
当然这里可以用both代替,如果遇到比较复杂的联合就需要 union
批量导入
janusGraph 本身不带有导入功能 我们使用github 开源工具 https://github.com/IBM/janusgraph-utils
下载工具ropo 打包
1 | git clone https://github.com/IBM/janusgraph-utils.git |
根据配置生成模版文件:
1 | ./run.sh gencsv csv-conf/twitter-like-w-date.json /tmp |
里面包括schama.json 描述各个字段类型,及索引等等,datamapper.json 描述各个节点及边所在的文件名,及各个字段对应关系。
导入数据
设置环境变量
1 | export JANUSGRAPH_HOME=/opt/app/janusgraph-0.3.1-hadoop2 |
1 | ./run.sh import ~/janusgraph/conf/janusgraph-cql-es.properties /tmp /tmp/schema.json /tmp/datamapper.json |
批量导入官方版本
官方导入方式 注意配置 hadoop 环境变量 最新版本的
环境变量
1 | export HADOOP_CONF_DIR=/etc/hadoop/conf |
配置文件
1 | gremlin.graph=org.apache.tinkerpop.gremlin.hadoop.structure.HadoopGraph |
1 | :load data/grateful-dead-janusgraph-schema.groovy |
清除数据
1 | :i org.janusgraph.core.util.JanusGraphCleanup |
查看schema
1 | graph = JanusGraphFactory.open('conf/gremlin-server/jianganwei-janusgraph-hbase-server.properties') |
添加节点
1 | tx = graph.newTransaction() |
添加边
1 | left=g.V(7372800004272).next() |
建立混合索引
1 | indexBuilder = mgmt.buildIndex("call_content_index", Edge.class) |
建立精准索引
1 | indexBuilder = mgmt.buildIndex("test_set_index", Vertex.class) |
添加属性
1 | mgmt.makePropertyKey("content").dataType(java.lang.String.class).cardinality(Cardinality.SINGLE).make() |
按混合索引查询数据
1 | graph.indexQuery("call_content_index","你").edgeTotals() |