当前位置: 首页 > 工具软件 > Gremlin > 使用案例 >

gremlin 语法

卢英范
2023-12-01

gremlin中文文档

一、属性、顶点、边操作

1、创建属性 PropertyKey

// 创建name属性,数据类型为 text,基数默认
graph.schema().propertyKey("name").asText().ifNotExist().create()
// 创建name属性,数据类型为 int,基数默认
graph.schema().propertyKey("age").asInt().ifNotExist().create()
// other,数据类型为text,基数为set
graph.schema().propertyKey("other").asText().valueSet().ifNotExist().create()

2、创建顶点

// 创建person顶点,属性为name,age,使用自定义数字id策略,name不能为空
graph.schema().vertexLabel("person").properties("name", "age").useCustomizeNumberId().nullableKeys("name").ifNotExist().create()

// 使用 PrimaryKey  Id策略	graph.schema().vertexLabel("person").properties("name","age").primaryKeys("name").ifNotExist().create();
graph.schema().vertexLabel("person").usePrimaryKeyId().properties("name","age").primaryKeys("name").ifNotExist().create();

// 使用自动生成id
graph.schema().vertexLabel("人员").properties("坐标_经度","姓名","出生日期","坐标_纬度").nullableKeys("坐标_经度","出生日期","坐标_纬度").useAutomaticId().ifNotExist().create()

// 使用自定义字符串
graph.schema().vertexLabel("person").properties("name", "age", "addr", "weight").useCustomizeStringId().ifNotExist().create()

  3、创建边

// 边关系为person到person的边,名称relation,边属性为relation
graph.schema().edgeLabel("relation").sourceLabel("person").targetLabel("person").properties("relation").ifNotExist().create()

4、添加数据

// T.label 为顶点名,T.id 为自定义主键数字
graph.addVertex(T.label, "person", T.id, 2001,"name", "巴达克", "age", 100)
graph.addVertex(T.label, "person", T.id, 2002,"name", "孙悟空", "age", 40)

// addV('company') 为指定顶点类型 company, property('name', '中石油') 为kv属性及值
g.addV('company').property('name', '中石油').property('city', '北京').property('addr', '中国北京市高新区')

// 使用自定义字符串主键加 property(id, 'java')
g.addV('software').property('name', 'java').property('weight', 1).property(id, 'java')

// 使用自定义字符串主键加 property(id, 'java')
g.addV('software').property('name', 'java').property('weight', 1).property(id, 'java')

// 使用 PrimaryKey  Id策略时,id主键 不能设置 T.id
graph.addVertex(T.label, "software", "id", 111, "name", "java", "weight", "1")

// 使用 PrimaryKey  Id策略时,非id主键策略,自定义数字策略,显式设置T.id
graph.addVertex(T.label, "person", T.id, 111, "id", 111,"name", "marko", "age", 29, "sex", "男", "addr", "陕西西安", "weight", "1")

5、绑定关系

// 方法一
g.V(2001).addE('relation').to(g.V(2002)).property('relation','儿子')
g.V(2002).addE('relation').to(g.V(2002)).property('relation','父亲')


// 方法二
to = g.V(2001)
from = g.V(2002)
g.addE('relation').from(from).to(to).property('relation','父亲')

// 方法三
javeme = graph.addVertex(T.label, "person", T.id, "javeme", "name", "Jermy Li", "age", 29, "addr", "Beijing", "weight", 1)
zhoney = graph.addVertex(T.label, "person", T.id, "zhoney", "name", "Zhoney Zhang", "age", 29, "addr", "Beijing", "weight", 1)

javeme.addEdge("knows", zhoney, "weight", 1)

6、创建索引

// 范围索引
graph.schema().indexLabel('personByAgeRange').onV('person').by('age').range().ifNotExist().create()

// 二级索引
graph.schema().indexLabel('personByName').onV('person').by('name').secondary().ifNotExist().create()

// 全文索引
graph.schema().indexLabel('personByNameFull').onV('person').by('age').search().ifNotExist().create()
		

// 索引类型
		interface	indexType	description
		secondary()	Secondary	support prefix search
		range()		Range		support range(numeric or date type) search
		search()	Search		support full text search
		shard()		Shard		support prefix + range(numeric or date type) search
		unique()	Unique		support unique props value, not support search

7、删除

-- 删除顶点
g.V('600').drop()

-- 删除边关系
g.E(id).drop()

-- 删除索引
schema.indexLabel("personByAge").remove()

二、查询

1、日期类型查询

// 使用where查询日期
g.V().hasLabel('person').where(values('创建时间').is(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse('1990-07-01 00:00:00.000')))

// 使用filter查询日期
g.V().hasLabel('person').filter {it.get().value('创建时间') == new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse('1990-07-01 00:00:00.000')}

// 将日期属性转化为日期字符串比较
g.V().hasLabel("person").filter{new java.text.SimpleDateFormat("yyyy-MM-dd").format(it.get().value("创建时间")) == '1990-07-01'}

2、条件查询 多条件or和and组合查询

// 多条件or和and组合查询
g.V()
.hasLabel('古建筑', '企业', '人')
.or(
  	and(values('地理_经度').is(gt(116.38571098899912)), values('地理_经度').is(lt(116.42085172218476)), values('地理_纬度').is(gt(39.910126452476156)), values('地理_纬度').is(lt(39.937075910999745))),
  	and(values('经度').is(gt(116.38571098899912)), values('经度').is(lt(116.42085172218476)), values('纬度').is(gt(39.910126452476156)), values('纬度').is(lt(39.937075910999745)))
 )
.where(
    values('地址').is(eq('北京市'))
)

3、查询顶点信息


	1、查询
		g.V()
		
	2、查询所有点,但限制点的返回数量
		g.V().limit(5)
		
	3、使用range(x, y)的算子,返回区间内的点数量
		g.V().range(0,5)
		
	4、查找label值的节点数据
		g.V().hasLabel('person')
		
	5、通过id查询节点
		g.V('javeme')

	6、 查询点的name属性
		g.V().values('name')
		
	7、dedup() (filter) 单步可以用来在整个遍历流中去重。 注意如果一个遍历的批量如果大于1,那么它在发出前就被设置成1了
		g.V().values('age').dedup()
		
	8、查询指定节点出度out(label):根据指定的 Edge Label 来访问顶点的 OUT 方向邻接点
	
		查询一级出度
		g.V('8').out()
		
		查询二级出度
		g.V('8').out().out()
		
		查询顶点id='javeme'所有边中向外指的顶点,返回这些顶点的name的值
		g.V('javeme').out().values('name')
		
		
		.V()查询定点, .out() 输出的顶点,.values("name") 属性为name的值
		
	9、path() 单步来检测它的路径实现
		g.V('8').out().out().dedup().path()
		
	10、获得经过的边的信息 bothE().otherV()
		g.V('8').out().out().bothE().otherV().path()
		
	11、simplePath(),过滤掉路径中含有环路的对象,只保留路径中不含有环路的对象
		g.V('8').out().out().simplePath()
		
	12、cyclicPath(),过滤掉路径中不含有环路的对象,只保留路径中含有环路的对象
		g.V('8').out().out().cyclicPath()
	
	13、统计
		g.V('8').out().out().count()
		
		
	14、使用map的方式,查询顶点id='javeme'所有边中向外指的顶点,返回这些顶点的name的值

		g.V('javeme').out().map {it.get().value('name')}
		
		和上面的区别在于,value中的属性必须都有,否则报错,而.values("name")属性不存在会忽略
		
		g.V('javeme').out().map(values('name'))
		
	15、删除节点
		g.V('600').drop()
		
	16、查询点的所有属性
		g.V().limit(3).valueMap()
		
	17、查询点的所有label
		g.V().label()
		
	18、获取顶点、边的属性值
		g.V().properties().value()
		g.V().values()
	
	19、properties():获取顶点、边的属性
		g.V().properties('name')
		
	20、in(label) 顶点为基准 根据指定的 Edge Label 来访问顶点的 IN 方向邻接点
	
		g.V('zhoney').in()
		g.V('zhoney').in('knows')

	21、both(label) 顶点为基准 根据指定的 Edge Label 来访问顶点的双向邻接点
		g.V('zhoney').both()
		g.V('zhoney').both('knows')
		
	22、bothV() 以边为基准 访问边的双向顶点
	
		g.E('Sokram>9>>Szhoney').bothV()
		
	23、outV() 以边为基准 访问边的出顶点,出顶点是指边的起始顶点
		g.E('Sokram>9>>Szhoney').outV()
		
	24、inV() 以边为基准 访问边的入顶点,入顶点是指边的目标顶点,也就是箭头指向的顶点
		g.E('Sokram>9>>Szhoney').inV()
	
	25、otherV() 以边为基准 访问边的伙伴顶点
		g.V('zhoney').outE().otherV()
		
	26、valueMap() 输出属性的key-value对
		g.V(2002).valueMap()
		
	27、select(key1,...,keyN)从map中取出需要的属性
		g.V(2002).valueMap().select("name", "identity")
		
	28、properties() 查询属性,对每个顶点/边返回一个mapping
		g.V(2002).properties()
		
	29、values(key1,...,keyN)取出节点/边的属性,返回列表
		g.V(2002).values() 返回所有属性值
		g.V(2002).values('name', 'age') 返回指定属性值
		
	30、tail(N) 尾部截取N个数据
		g.V().tail(10) 取最后10条数据
		g.V().tail() 取最后一条数据

 4、查询边信息

    1、查询所有边
		g.E()
	
	2、查询指定数量边
		g.E().limit(4)
	
	3、查询指定区间边
		g.E().range(2,4)
		
	4、通过边id查询
		g.E('S8:中石油>6>>Szhoney')
		
	5、通过边类型查询边
		g.E().hasLabel('use')
		
	6、删除边
		g.E('S8:中石油>6>>Szhoney').drop()
	
	7、顶点为基准 查询某个点的指定出边
		g.V('okram').outE()
		
		查询某个顶点 use 出边
		g.V('okram').outE('use')
		
	8、顶点为基准 查询某个点的指定入边
		g.V('zhoney').inE()
		
		查询某个顶点 use 入边
		g.V('zhoney').inE('staff')
		
	9、顶点为基准 bothE(label) 根据指定的 Edge Label 来访问顶点的双向邻接边
		g.V('zhoney').bothE()
		g.V('zhoney').bothE('knows')

三、has的用法类似于过滤器的作用

在HugeGraph中,按property的值查询之前,应该对property建立索引,否则将无法查到结果并引发异常,
	如下,执行下面语句报错
		g.V().has('name', 'Marko A. Rodriguez').next()
	异常:
	Gremlin 执行失败,详细信息: Don't accept query based on properties [name] that are not indexed in any label, may not match secondary condition

	解决方法:
	对person的name属性建立secondary索引,可以对Text类型property按值进行查询
	graph.schema().indexLabel('personByName').onV('person').by('name').secondary().ifNotExist().create()
	

	1、查找所有顶点中label边的值为person的(默认返回节点信息)
		g.V().hasLabel('person')
		
	2、一个过滤器(filter)操作,过滤条件是顶点的标签是"person"
	
		g.V().filter(label().is('person')).limit(100)
		可能会报  Gremlin 执行失败,详细信息: Too many records(must <= 800000) for the query: `Query * from VERTEX`
	
	3、通过name属性查询 (前提条件建立索引)
		g.V().has('name', 'Zhoney Zhang')
		
		精确查询集合内的数据
		g.V().has('name', within('Marko A. Rodriguez', 'Zhoney Zhang'))
		
		查询年龄29的定点
		g.V().has('age', 29)
		
	4、hasKey(keys…​) 通过 properties 中的若干 key 过滤顶点或边
		g.V().properties().hasKey('age')
		
	5、hasValue(values…​): 通过 properties 中的若干 value 过滤顶点或边
		g.V().properties().hasValue(29)
		
	6、has(key) properties 中存在 key 这个属性则通过,等价于hasKey(key)
		g.V().has('age')

四、where查询

g.V().hasLabel('人').where(values('名称').is(eq('秦始皇')).and().values('年龄').is(eq(60)))

g.V(613794531921362945).both().hasLabel('企业').both('历史').where(has('地理_纬度').and().has('创建时间').and().values('创建时间').is(gt(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse('2011-07-01 00:00:00')))).order().by('创建时间')

g.V(613794531921362945).both().hasLabel('企业').both('历史').where(has('地理_纬度').and().has('创建时间')).order().by('创建时间')


类似其他语法中有比较值或值的范围的语句,gremlin中这类比较语句的Predicates
	1、eq()	等于
	2、neq()	不等于
	3、gt()	大于
	4、gte()	大于或等于
	5、lt()	小于
	6、lte()	小于或等于
	7、inside(a, b)	是否在开区间(a, b)
	8、outside(a,b)	是否在开区间(a,b)外
	9、between(a, b)	是否在区间[a, b)内
	10、within	是否在list/range中
	11、without	是否在/list/range外

五、使用hugeGraph创建数据库

        1、进入服务安装目录

        2、在 /conf 目录下创建 hugemysql2.properties 配置文件,并修改自己的数据库信息

        3、修改 rest-server.properties 在 graphs=[hugemysql: conf/hugemysql.properties] 添加配置信息

        4、修改 gremlin-server.yaml,在  graphs 标签中添加配置文件路径

                graphs: {
                    hugemysql2: conf/hugemysql2.properties
                }

        5、进入 bin 目录,停止服务 sh stop-hugegraph.sh

        6、安装服务,sh init-store.sh

        7、重启服务,sh start-hugegraph.sh

        8、在页面新建连接

六、问题

1、Gremlin 执行失败,详细信息: Don't accept query based on properties [name] that are not indexed in any label, may not match secondary condition

解决方法
对person的name属性建立secondary索引,可以对Text类型property按值进行查询
graph.schema().indexLabel('personByName').onV('person').by('name').secondary().ifNotExist().create()

2、Gremlin 执行失败,详细信息: Don't accept query based on properties [age] that are not indexed in any label, may not match range condition

3、Gremlin 执行失败,详细信息: Don't accept query based on properties [name] that are not indexed in any label, may not match not-equal condition
g.V().has('name',without('java','Zhoney Zhang')) 报错 within 可以,without不行

 类似资料: