from:https://rednum.cn/ViewListAction?method=detail&dataid=315&classfyid=1
接触Titan数据库是去年的事情了,今年公司要开发一个新的的关系发现系统,所以把自己掌握的关于Titan的知识记录一下。这篇文章一共有三章,由我和同事合著完成。
1.Titan数据的安装
下载地址:http://s3.thinkaurelius.com/downloads/titan/titan-1.0.0-hadoop1.zip
从titan的官网上我们会看到titan数据是一种非常灵活的数据,可以有一些很多的组合方式:
小编使用的是 Hbase + ElasticSearch + db-cache 方式使用Titan
Hbase,ES,和配置的时候都可以是集群的方式,考虑到时入门这里使用Hbase是集群的方式,其它都是单节点的方式
3.启动Titan客户端 gremlin
$ bin/titan.sh start
Forking Cassandra...
Running `nodetool statusthrift`.. OK (returned exit status 0 and printed string "running").
Forking Elasticsearch...
Connecting to Elasticsearch (127.0.0.1:9300)... OK (connected to 127.0.0.1:9300).
Forking Gremlin-Server...
Connecting to Gremlin-Server (127.0.0.1:8182)... OK (connected to 127.0.0.1:8182).
Run gremlin.sh to connect.
4.配置Titan的工作方式,进入目录conf我们看到有很多预配置的文件
$ bin/gremlin.sh
\,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.hadoop
plugin activated: tinkerpop.utilities
plugin activated: aurelius.titan
plugin activated: tinkerpop.tinkergraph
gremlin> :remote connect tinkerpop.server conf/remote.yaml
# Titan configuration sample: HBase and Elasticsearch
#
# This file connects to HBase using a Zookeeper quorum
# (storage.hostname) consisting solely of localhost. It also connects
# to Elasticsearch running on localhost over Elasticsearch's native "Transport"
# protocol. Zookeeper, the HBase services, and Elasticsearch must already
# be running and available before starting Titan with this file.
# The primary persistence provider used by Titan. This is required. It
# should be set one of Titan's built-in shorthand names for its standard
# storage backends (shorthands: berkeleyje, cassandrathrift, cassandra,
# astyanax, embeddedcassandra, hbase, inmemory) or to the full package and
# classname of a custom/third-party StoreManager implementation.
#
# Default: (no default value)
# Data Type: String
# Mutability: LOCAL
storage.backend=hbase
# The hostname or comma-separated list of hostnames of storage backend
# servers. This is only applicable to some storage backends, such as
# cassandra and hbase.
#
# Default: 127.0.0.1
# Data Type: class java.lang.String[]
# Mutability: LOCAL
storage.hostname=192.168.1.252
# Whether to enable Titan's database-level cache, which is shared across
# all transactions. Enabling this option speeds up traversals by holding
# hot graph elements in memory, but also increases the likelihood of
# reading stale data. Disabling it forces each transaction to
# independently fetch graph elements from storage before reading/writing
# them.
#
# Default: false
# Data Type: Boolean
# Mutability: MASKABLE
cache.db-cache = true
# How long, in milliseconds, database-level cache will keep entries after
# flushing them. This option is only useful on distributed storage
# backends that are capable of acknowledging writes without necessarily
# making them immediately visible.
#
# Default: 50
# Data Type: Integer
# Mutability: GLOBAL_OFFLINE
#
# Settings with mutability GLOBAL_OFFLINE are centrally managed in Titan's
# storage backend. After starting the database for the first time, this
# file's copy of this setting is ignored. Use Titan's Management System
# to read or modify this value after bootstrapping.
cache.db-cache-clean-wait = 20
# Default expiration time, in milliseconds, for entries in the
# database-level cache. Entries are evicted when they reach this age even
# if the cache has room to spare. Set to 0 to disable expiration (cache
# entries live forever or until memory pressure triggers eviction when set
# to 0).
#
# Default: 10000
# Data Type: Long
# Mutability: GLOBAL_OFFLINE
#
# Settings with mutability GLOBAL_OFFLINE are centrally managed in Titan's
# storage backend. After starting the database for the first time, this
# file's copy of this setting is ignored. Use Titan's Management System
# to read or modify this value after bootstrapping.
cache.db-cache-time = 180000
# Size of Titan's database level cache. Values between 0 and 1 are
# interpreted as a percentage of VM heap, while larger values are
# interpreted as an absolute size in bytes.
#
# Default: 0.3
# Data Type: Double
# Mutability: MASKABLE
cache.db-cache-size = 0.5
# The indexing backend used to extend and optimize Titan's query
# functionality. This setting is optional. Titan can use multiple
# heterogeneous index backends. Hence, this option can appear more than
# once, so long as the user-defined name between "index" and "backend" is
# unique among appearances.Similar to the storage backend, this should be
# set to one of Titan's built-in shorthand names for its standard index
# backends (shorthands: lucene, elasticsearch, es, solr) or to the full
# package and classname of a custom/third-party IndexProvider
# implementation.
#
# Default: elasticsearch
# Data Type: String
# Mutability: GLOBAL_OFFLINE
#
# Settings with mutability GLOBAL_OFFLINE are centrally managed in Titan's
# storage backend. After starting the database for the first time, this
# file's copy of this setting is ignored. Use Titan's Management System
# to read or modify this value after bootstrapping.
index.search.backend=elasticsearch
# The hostname or comma-separated list of hostnames of index backend
# servers. This is only applicable to some index backends, such as
# elasticsearch and solr.
#
# Default: 127.0.0.1
# Data Type: class java.lang.String[]
# Mutability: MASKABLE
index.search.hostname=127.0.0.1
# The Elasticsearch node.client option is set to this boolean value, and
# the Elasticsearch node.data option is set to the negation of this value.
# True creates a thin client which holds no data. False creates a regular
# Elasticsearch cluster node that may store data.
#
# Default: true
# Data Type: Boolean
# Mutability: GLOBAL_OFFLINE
#
# Settings with mutability GLOBAL_OFFLINE are centrally managed in Titan's
# storage backend. After starting the database for the first time, this
# file's copy of this setting is ignored. Use Titan's Management System
# to read or modify this value after bootstrapping.
index.search.elasticsearch.client-only=true
[========]
好回到gremlin.sh,在提示符下输入以下命令,看到类似的结果
gremlin> graph = TitanFactory.open('conf/titan-berkeleyje-es.properties')
==>standardtitangraph[berkeleyje:../db/berkeley]
gremlin> GraphOfTheGodsFactory.load(graph)
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[standardtitangraph[berkeleyje:../db/berkeley], standard]
那么恭喜您,你的第一个Titan数据建立好了,事实上titan已经在Hbase中建立了一个叫做titan的表,和在ES中建立一个叫Search的索引,运行以下的查询语句进一步验证:
gremlin> g
==>graphtraversalsource[titangraph[cassandrathrift:127.0.0.1], standard]
gremlin> g.V().has('name', 'hercules')
==>v[24]
gremlin> g.V().has('name', 'hercules').out('father')
==>v[16]
gremlin> g.V().has('name', 'hercules').out('father').out('father')
==>v[20]
gremlin> g.V().has('name', 'hercules').out('father').out('father').values('name')
==>saturn
在titan这个表中实际存储的是这样一个结构:
这个图对于初学者可能有点蒙逼,请大家不要在意这些细节,这个图讲的主要是希腊神话中神与神自己一些关系,比如谁和谁是兄弟,谁和谁是母女父子兄弟,谁在那里居住,谁在那里战斗过等等等…..
大家可以把这个图上的关系和上面的查询语句对照起来看就一目了然了,我举个例子:
g.V().has(‘name’, ‘hercules’).out(‘father’)
表示找一个顶点 V,它有一个属性 name = hercules,然后谁是他的的父亲关系的节点。
6 titan db数据规范
6.1 边的类型下面几种
MULTI:表示点和点之间没有约束,可以有任意多个边相连;
SIMPLE:表示点和点只有一个单向进入或出去的边;
MANY2ONE:表示一个点可以有多个进入边;
ONE2MANY:表示一个点可以有多个出去边;
ONE2ONE:表示两个点可以有一对边
示例代码:
mgmt = graph.openManagement()
follow = mgmt.makeEdgeLabel('follow').multiplicity(MULTI).make()
mother = mgmt.makeEdgeLabel('mother').multiplicity(MANY2ONE).make()
mgmt.commit()
6.2 titan数据支持类型
表示我们给点或边定义属性,而这些属性可以是以上的数据类型
6.3 属性的基数
SINGLE: 严格的key->value一对一
LIST:key->values一对多values可以重复
SET:key->values一对多values不可以重复
7.titan主要索引的使用
7.1 Composite Index
示例代码:
graph.tx().rollback() //Never create new indexes while a transaction is active
mgmt = graph.openManagement()
name = mgmt.getPropertyKey('name')
age = mgmt.getPropertyKey('age')
mgmt.buildIndex('byNameComposite', Vertex.class).addKey(name).buildCompositeIndex()
mgmt.buildIndex('byNameAndAgeComposite', Vertex.class).addKey(name).addKey(age).buildCompositeIndex()
mgmt.commit()
//Wait for the index to become available
mgmt.awaitGraphIndexStatus(graph, 'byNameComposite').call()
mgmt.awaitGraphIndexStatus(graph, 'byNameAndAgeComposite').call()
//Reindex the existing data
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getGraphIndex("byNameComposite"), SchemaAction.REINDEX).get()
mgmt.updateIndex(mgmt.getGraphIndex("byNameAndAgeComposite"), SchemaAction.REINDEX).get()
mgmt.commit()
这种只能用索引的值严格查找等于的方式查找;
7.2 Mixed Index
示例代码
graph.tx().rollback() //Never create new indexes while a transaction is active
mgmt = graph.openManagement()
name = mgmt.getPropertyKey('name')
age = mgmt.getPropertyKey('age')
mgmt.buildIndex('nameAndAge', Vertex.class).addKey(name).addKey(age).buildMixedIndex("search")
mgmt.commit()
//Wait for the index to become available
mgmt.awaitGraphIndexStatus(graph, 'nameAndAge').call()
//Reindex the existing data
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getGraphIndex("nameAndAge"), SchemaAction.REINDEX).get()
mgmt.commit()
这种Index必须使用ES作为后备,可以模糊查询或值范围查询
8.pom.xml 配置
xml version="1.0" encoding="UTF-8"?>
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.rednum.graph
redtitan
1.0-SNAPSHOT
jar
UTF-8
1.7
1.7
org.slf4j
slf4j-api
1.7.2
org.slf4j
slf4j-log4j12
1.7.2
log4j
log4j
1.2.16
javax.jms
jms
com.sun.jdmk
jmxtools
com.sun.jmx
jmxri
org.apache.hadoop
hadoop-hdfs
2.6.4
org.apache.hadoop
hadoop-client
2.6.4
org.apache.hbase
hbase-client
1.2.1
org.apache.hbase
hbase
1.2.1
pom
com.google.guava
guava
16.0.1
com.thinkaurelius.titan
titan-core
1.0.0
com.thinkaurelius.titan
titan-hbase
1.0.0
com.thinkaurelius.titan
titan-es
1.0.0
org.elasticsearch
elasticsearch
1.5.2
com.google.guava
guava
prohadoop
prohadoop
0.0.1-SNAPSHOT
jar
org.apache.maven.plugins
maven-compiler-plugin
1.7
1.8
org.apache.maven.plugins
maven-assembly-plugin
2.4
jar-with-dependencies
assemble-all
package
single
redtitan
9.titan java客户端
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.rednum.graph;
import com.google.gson.Gson;
import com.google.gson.internal.LinkedTreeMap;
import static com.rednum.graph.TiTanDB.INDEX_NAME;
import static com.rednum.graph.TiTanDB.load;
import static com.rednum.graph.TiTanDB.query;
import com.thinkaurelius.titan.core.EdgeLabel;
import com.thinkaurelius.titan.core.Multiplicity;
import com.thinkaurelius.titan.core.PropertyKey;
import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;
import com.thinkaurelius.titan.core.TitanTransaction;
import com.thinkaurelius.titan.core.attribute.Geoshape;
import com.thinkaurelius.titan.core.attribute.Text;
import com.thinkaurelius.titan.core.schema.ConsistencyModifier;
import com.thinkaurelius.titan.core.schema.TitanGraphIndex;
import com.thinkaurelius.titan.core.schema.TitanManagement;
import com.thinkaurelius.titan.core.util.TitanCleanup;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.configuration.BaseConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.tinkerpop.gremlin.process.traversal.Order;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
/**
*
* @author X.H.Yang
*/
public class TitanNewGraph {
// private final Gson gson = new Gson();
public static TitanGraph create() {
try {
//创建名为temptest的表。
TitanGraph graph = TitanFactory.build()
.set("storage.backend", "hbase")
.set("storage.hostname", "192.168.1.252")
.set("storage.hbase.table", "newgraph")
.set("cache.db-cache", "true")
.set("cache.db-cache-clean-wait", "20")
.set("cache.db-cache-time", "180000")
.set("cache.db-cache-size", "0.5")
.set("index.newgraph.backend", "elasticsearch")
.set("index.newgraph.hostname", "192.168.1.212")
.set("index.newgraph.port", 9300)
.set("index.newgraph.elasticsearch.client-only", true)
.open();
return graph;
} catch (Exception e) {
System.out.println(e);
return null;
}
}
public static void loadWithoutMixedIndex(final TitanGraph graph,
boolean uniqueNameCompositeIndex) {
load(graph, null, uniqueNameCompositeIndex);
}
public static void load(final TitanGraph graph) {
load(graph, "newgraph", true);
}
public static void load(final TitanGraph graph, String mixedIndexName,
boolean uniqueNameCompositeIndex) {
// Create Schema
try {
TitanManagement mgmt = graph.openManagement();
final PropertyKey name = mgmt.makePropertyKey("name").dataType(String.class).make();
TitanManagement.IndexBuilder nameIndexBuilder = mgmt.buildIndex("name", Vertex.class).addKey(name);
if (uniqueNameCompositeIndex) {
nameIndexBuilder.unique();
}
TitanGraphIndex namei = nameIndexBuilder.buildCompositeIndex();
mgmt.setConsistency(namei, ConsistencyModifier.LOCK);
final PropertyKey age = mgmt.makePropertyKey("age").dataType(Integer.class).make();
if (null != mixedIndexName) {
mgmt.buildIndex("vertices", Vertex.class).addKey(age).buildMixedIndex(mixedIndexName);
}
final PropertyKey time = mgmt.makePropertyKey("time").dataType(Integer.class).make();
final PropertyKey reason = mgmt.makePropertyKey("reason").dataType(String.class).make();
final PropertyKey place = mgmt.makePropertyKey("place").dataType(Geoshape.class).make();
if (null != mixedIndexName) {
mgmt.buildIndex("edges", Edge.class).addKey(reason).addKey(place).buildMixedIndex(mixedIndexName);
}
mgmt.makeEdgeLabel("father").multiplicity(Multiplicity.MANY2ONE).make();
mgmt.makeEdgeLabel("mother").multiplicity(Multiplicity.MANY2ONE).make();
EdgeLabel battled = mgmt.makeEdgeLabel("battled").signature(time).make();
mgmt.buildEdgeIndex(battled, "battlesByTime", Direction.BOTH, Order.decr, time);
mgmt.makeEdgeLabel("lives").signature(reason).make();
mgmt.makeEdgeLabel("pet").make();
mgmt.makeEdgeLabel("brother").make();
mgmt.makeVertexLabel("titan").make();
mgmt.makeVertexLabel("location").make();
mgmt.makeVertexLabel("god").make();
mgmt.makeVertexLabel("demigod").make();
mgmt.makeVertexLabel("human").make();
mgmt.makeVertexLabel("monster").make();
mgmt.commit();
TitanTransaction tx = graph.newTransaction();
// vertices
Vertex saturn = tx.addVertex(T.label, "titan", "name", "saturn", "age", 34);
Vertex sky = tx.addVertex(T.label, "location", "name", "sky");
Vertex sea = tx.addVertex(T.label, "location", "name", "sea");
Vertex jupiter = tx.addVertex(T.label, "god", "name", "jupiter", "age", 5000);
Vertex neptune = tx.addVertex(T.label, "god", "name", "neptune", "age", 4500);
Vertex hercules = tx.addVertex(T.label, "demigod", "name", "hercules", "age", 30);
Vertex alcmene = tx.addVertex(T.label, "human", "name", "alcmene", "age", 45);
Vertex pluto = tx.addVertex(T.label, "god", "name", "pluto", "age", 4000);
Vertex nemean = tx.addVertex(T.label, "monster", "name", "nemean");
Vertex hydra = tx.addVertex(T.label, "monster", "name", "hydra");
Vertex cerberus = tx.addVertex(T.label, "monster", "name", "cerberus");
Vertex tartarus = tx.addVertex(T.label, "location", "name", "tartarus");
// edges
jupiter.addEdge("father", saturn);
jupiter.addEdge("lives", sky, "reason", "loves fresh breezes");
jupiter.addEdge("brother", neptune);
jupiter.addEdge("brother", pluto);
neptune.addEdge("lives", sea).property("reason", "loves waves");
neptune.addEdge("brother", jupiter);
neptune.addEdge("brother", pluto);
hercules.addEdge("father", jupiter);
hercules.addEdge("mother", alcmene);
hercules.addEdge("battled", nemean, "time", 1, "place", Geoshape.point(38.1f, 23.7f));
hercules.addEdge("battled", hydra, "time", 2, "place", Geoshape.point(37.7f, 23.9f));
hercules.addEdge("battled", cerberus, "time", 12, "place", Geoshape.point(39f, 22f));
pluto.addEdge("brother", jupiter);
pluto.addEdge("brother", neptune);
pluto.addEdge("lives", tartarus, "reason", "no fear of death");
pluto.addEdge("pet", cerberus);
cerberus.addEdge("lives", tartarus);
//commit the transaction to disk
tx.commit();
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
public static void query(TitanGraph graph) {
GraphTraversalSource g = graph.traversal();
GraphTraversal<Vertex, Long> count = g.V().count();
System.out.println("共有结点" + count.next());
GraphTraversal<Vertex, Vertex> iterators = g.V();
try {
while (iterators.hasNext()) {
Vertex ver = iterators.next();
System.out.println(ver);
System.out.println(ver.label());
System.out.println(ver.keys());
Set<String> set = ver.keys();
for (String ss : set) {
System.out.println(ver.value(ss));
}
}
} catch (Exception e) {
e.toString();
}
GraphTraversal<Edge, Edge> edgeAll = g.E();
System.out.println("共有边" + g.E().count().next());
try {
while (edgeAll.hasNext()) {
Edge ee = edgeAll.next();
Set<String> set = ee.keys();
for (String ss : set) {
System.out.println(ss+":"+ee.value(ss));
}
System.out.println(ee.label());
System.out.println(ee.outVertex().value("name"));
System.out.println(ee.inVertex().value("name"));
System.out.println("-----");
}
} catch (Exception e) {
e.toString();
}
System.out.println(g.V().has("name", "hercules").next().value("name"));
System.out.println(g.V().has("name", "hercules").next().values("name", "age"));
Iterator<Object> iterator = g.V().has("name", "hercules").next().values("name", "age");
while (iterator.hasNext()) {
Object object = iterator.next();
System.out.println(object);
}
Vertex saturn = g.V().has("name", "tanzhuo").next();
System.out.println(saturn);
//得到 saturn的孙子节点
System.out.println(g.V(saturn).in("father").in("father").next().value("age"));
GraphTraversal<Edge, Edge> a = g.E().has("place", P.eq(Geoshape.point(38.1f, 23.7f)));
System.out.println(a);
while (a.hasNext()) {
Edge e = a.next();
System.out.println(e.keys());
System.out.println(e.label());
System.out.println(e.outVertex().value("name"));
System.out.println(e.inVertex().value("name"));
System.out.println(e.value("time") + " : " + e.value("place"));
}
Vertex hercules = g.V().has("name", "hercules").next();
System.out.println(g.V(hercules).out("mother", "father").values("name"));
GraphTraversal<Vertex, Vertex> mF = g.V(hercules).out("mother", "father");
while (mF.hasNext()) {
Vertex v = mF.next();
System.out.println(v.label() + " : " + v.value("name"));
}
//repeat(__.in("father")).times(2)表示父亲的父亲,times(2)表示重复两次
System.out.println(g.V(saturn).repeat(__.in("father")).times(2).next().value("name"));
GraphTraversal<Vertex, Vertex> monsters = g.V(hercules).out("battled");
while (monsters.hasNext()) {
Vertex monster = monsters.next();
System.out.println(monster.label() + " : " + monster.value("name"));
}
//P.eq(1)表示time,次数为1次
monsters = g.V(hercules).outE("battled").has("time", P.eq(1)).inV();
while (monsters.hasNext()) {
Vertex monster = monsters.next();
System.out.println(monster.label() + " : " + monster.value("name"));
}
Vertex pluto = g.V().has("name", "pluto").next();
GraphTraversal<Vertex, Vertex> liveInTartarusVertex = g.V(pluto).out("lives").in("lives");
while (liveInTartarusVertex.hasNext()) {
Vertex vertex = liveInTartarusVertex.next();
System.out.println(vertex.value("name"));
}
GraphTraversal<Vertex, Vertex> liveInTartarusVertexNo = g.V(pluto).out("lives").in("lives").where(__.is(P.neq(pluto)));
while (liveInTartarusVertexNo.hasNext()) {
Vertex vertex = liveInTartarusVertexNo.next();
System.out.println(vertex.value("name"));
}
//P.neq("x")不等于
GraphTraversal<Vertex, Vertex> liveInTartarusVertexNot = g.V(pluto).as("x").out("lives").in("lives").where(P.neq("x"));
while (liveInTartarusVertexNot.hasNext()) {
Vertex vertex = liveInTartarusVertexNot.next();
System.out.println("======" + vertex.value("name"));
}
GraphTraversal<Vertex, Map<String, Vertex>> brothers
= g.V(pluto).out("brother").as("god").out("lives").as("place").select("god", "place");
while (brothers.hasNext()) {
Map<String, Vertex> map = brothers.next();
System.out.println(map);
for (Map.Entry<String, Vertex> entry : map.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue().value("name"));
}
}
System.out.println(g.V(pluto).outE("lives").next().value("reason"));
GraphTraversal<Edge, Edge> reasons = g.E().has("reason").as("r").values("reason").is(Text.textContains("loves")).select("r");
System.out.println(reasons);
while (reasons.hasNext()) {
Edge e = reasons.next();
System.out.println(e.keys());
System.out.println(e.label());
System.out.println(e.value("reason"));
}
GraphTraversal<Edge, Map<String, Object>> reasons2
= g.E().has("reason").as("source").values("reason").is(Text.textContains("loves")).as("reason").select("source")
.outV().values("name").as("god").select("source").inV().values("name").as("thing").select("god", "reason", "thing");
while (reasons2.hasNext()) {
Map<String, Object> map = reasons2.next();
System.out.println(map);
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
}
}
public static void main(String[] args) throws Exception {
try {
TitanGraph graph = TitanNewGraph.create();
//load(graph);
query(graph);
graph.close();
} catch (Exception e) {
e.toString();
}
}
}
10.程序输出
共有结点12
v[4120]
location
[name]
sky
v[8216]
location
[name]
sea
v[4160]
human
[name, age]
alcmene
45
v[8256]
god
[name, age]
pluto
4000
v[12352]
location
[name]
tartarus
v[4200]
god
[name, age]
jupiter
5000
v[8296]
monster
[name]
nemean
v[4208]
monster
[name]
hydra
v[4224]
titan
[name, age]
tanzhuo
34
v[8320]
monster
[name]
cerberus
v[4304]
god
[name, age]
neptune
4500
v[4336]
demigod
[name, age]
hercules
30
共有边17
reason:no fear of death
lives
pluto
tartarus
-----
pet
pluto
cerberus
-----
brother
pluto
jupiter
-----
brother
pluto
neptune
-----
father
jupiter
tanzhuo
-----
reason:loves fresh breezes
lives
jupiter
sky
-----
brother
jupiter
neptune
-----
brother
jupiter
pluto
-----
lives
cerberus
tartarus
-----
reason:loves waves
lives
neptune
sea
-----
brother
neptune
jupiter
-----
brother
neptune
pluto
-----
father
hercules
jupiter
-----
mother
hercules
alcmene
-----
place:point[37.7,23.9]
time:2
battled
hercules
hydra
-----
time:1
place:point[38.1,23.7]
battled
hercules
nemean
-----
place:point[39.0,22.0]
time:12
battled
hercules
cerberus
-----
hercules
org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils$3@b1534d3
hercules
30
v[4224]
30
[GraphStep([],edge), HasStep([place.eq(point[38.1,23.7])])]
[time, place]
battled
hercules
nemean
1 : point[38.1,23.7]
[GraphStep([v[4336]],vertex), VertexStep(OUT