Gremlin语法入门 #
一、Gremlin概述 #
1.1 什么是Gremlin #
Gremlin是Apache TinkerPop图计算框架的图遍历语言,用于查询和操作属性图数据。
text
Gremlin特点:
├── 函数式编程风格
├── 流式数据处理
├── 支持复杂图遍历
├── 多语言驱动支持
└── 可扩展性强
1.2 基本结构 #
gremlin
// 基本结构
g.遍历源.遍历步骤1().遍历步骤2()...终端步骤()
// 示例
g.V().hasLabel('person').values('name').limit(10)
1.3 遍历步骤分类 #
text
遍历步骤分类:
├── 源步骤(Source Steps)
├── 过滤步骤(Filter Steps)
├── 变换步骤(Transform Steps)
├── 侧效步骤(SideEffect Steps)
└── 终端步骤(Terminal Steps)
二、源步骤 #
2.1 V() - 顶点源 #
gremlin
// 获取所有顶点
g.V()
// 获取指定ID的顶点
g.V('1')
g.V('1', '2', '3')
// 获取指定标签的顶点
g.V().hasLabel('person')
2.2 E() - 边源 #
gremlin
// 获取所有边
g.E()
// 获取指定ID的边
g.E('e1')
g.E('e1', 'e2', 'e3')
// 获取指定标签的边
g.E().hasLabel('knows')
2.3 inject() - 注入数据 #
gremlin
// 注入值
g.inject(1, 2, 3)
// 注入对象
g.inject(['name': 'Tom', 'age': 30])
// 用于批量操作
g.inject(['Tom', 'Jerry', 'Mike']).unfold().addV('person').property('name', identity)
三、过滤步骤 #
3.1 has() - 属性过滤 #
gremlin
// 精确匹配
g.V().has('name', 'Tom')
g.V().has('name', eq('Tom'))
// 比较操作
g.V().has('age', gt(25)) // 大于
g.V().has('age', gte(25)) // 大于等于
g.V().has('age', lt(40)) // 小于
g.V().has('age', lte(40)) // 小于等于
g.V().has('age', neq(30)) // 不等于
// 区间
g.V().has('age', inside(20, 40)) // 20 < age < 40
g.V().has('age', outside(20, 40)) // age < 20 或 age > 40
// 列表匹配
g.V().has('name', within('Tom', 'Jerry', 'Mike'))
g.V().has('name', without('Tom', 'Jerry'))
// 字符串匹配
g.V().has('name', containing('om'))
g.V().has('name', startingWith('T'))
g.V().has('name', endingWith('m'))
g.V().has('name', regex('T.*m'))
3.2 hasLabel() - 标签过滤 #
gremlin
// 单标签
g.V().hasLabel('person')
// 多标签
g.V().hasLabel('person', 'employee')
// 边标签
g.E().hasLabel('knows', 'follows')
3.3 hasNot() - 属性不存在 #
gremlin
// 属性不存在
g.V().hasNot('email')
// 等价于
g.V().not(has('email'))
3.4 filter() - 条件过滤 #
gremlin
// 使用filter
g.V().filter(outE().count().is(gt(0)))
// 使用Lambda(注意性能)
g.V().filter { it.get().property('name').orElse('') == 'Tom' }
3.5 where() - 条件过滤 #
gremlin
// 简单条件
g.V().where(outE().count().is(gt(5)))
// 使用标记
g.V().as('a').out('knows').as('b').
where('a', neq('b'))
// 使用by修饰
g.V().as('a').out('knows').as('b').
where('a', neq('b')).by('name')
3.6 dedup() - 去重 #
gremlin
// 简单去重
g.V().out('knows').dedup()
// 按属性去重
g.V().dedup().by('name')
// 按标记去重
g.V().as('a').out('knows').as('b').dedup('a', 'b')
3.7 逻辑操作 #
gremlin
// AND
g.V().and(
has('age', gt(25)),
has('name', startingWith('T'))
)
// OR
g.V().or(
has('name', 'Tom'),
has('name', 'Jerry')
)
// NOT
g.V().not(has('status', 'inactive'))
四、变换步骤 #
4.1 out()/in()/both() - 边遍历 #
gremlin
// 出边遍历
g.V('1').out() // 所有出边
g.V('1').out('knows') // 指定标签出边
// 入边遍历
g.V('1').in() // 所有入边
g.V('1').in('knows') // 指定标签入边
// 双向遍历
g.V('1').both() // 所有边
g.V('1').both('knows') // 指定标签双向边
4.2 outE()/inE()/bothE() - 获取边 #
gremlin
// 获取出边
g.V('1').outE()
g.V('1').outE('knows')
// 获取入边
g.V('1').inE()
g.V('1').inE('knows')
// 获取所有边
g.V('1').bothE()
4.3 inV()/outV()/bothV() - 获取顶点 #
gremlin
// 从边获取顶点
g.E('e1').inV() // 入顶点
g.E('e1').outV() // 出顶点
g.E('e1').bothV() // 两个顶点
// 链式操作
g.V('1').outE().inV() // 等同于 g.V('1').out()
g.V('1').inE().outV() // 等同于 g.V('1').in()
4.4 map()/flatMap() - 映射 #
gremlin
// map - 一对一映射
g.V().map(values('name'))
g.V().map(outE().count())
// flatMap - 一对多映射
g.V().flatMap(out('knows'))
g.V().flatMap(values('name', 'email'))
4.5 select() - 选择 #
gremlin
// 选择标记
g.V().as('a').out('knows').as('b').select('a', 'b')
// 选择属性
g.V().as('a').out('knows').as('b').
select('a', 'b').by('name')
// 选择所有标记
g.V().as('a').out('knows').as('b').select(all)
4.6 path() - 路径 #
gremlin
// 获取路径
g.V('1').out('knows').path()
// 路径属性
g.V('1').out('knows').path().by('name')
// 简单路径(无环)
g.V('1').repeat(out()).times(3).simplePath()
4.7 values()/valueMap() - 获取值 #
gremlin
// 获取单个属性值
g.V().values('name')
// 获取多个属性值
g.V().values('name', 'age')
// 获取所有属性值
g.V().values()
// 获取属性映射
g.V().valueMap()
// 获取属性映射(包含ID和标签)
g.V().valueMap(true)
五、聚合步骤 #
5.1 count() - 计数 #
gremlin
// 计数
g.V().count()
// 条件计数
g.V().has('status', 'active').count()
// 分组计数
g.V().groupCount().by('status')
5.2 group() - 分组 #
gremlin
// 简单分组
g.V().group().by('status')
// 分组聚合
g.V().group().
by('status').
by('age', mean())
// 多级分组
g.V().group().
by('status').
by(group().by('department'))
5.3 order() - 排序 #
gremlin
// 升序排序
g.V().order().by('name')
// 降序排序
g.V().order().by('name', desc)
// 多属性排序
g.V().order().by('status', asc).by('name', asc)
// 按计算值排序
g.V().order().by(outE().count(), desc)
5.4 limit()/range() - 分页 #
gremlin
// 限制数量
g.V().limit(10)
// 跳过前N条
g.V().range(10, 20) // 第11-20条
// Tail
g.V().order().by('name').tail(10)
5.5 sum()/mean()/max()/min() - 聚合 #
gremlin
// 求和
g.V().values('age').sum()
// 平均值
g.V().values('age').mean()
// 最大值
g.V().values('age').max()
// 最小值
g.V().values('age').min()
六、终端步骤 #
6.1 toList()/next()/iterate() #
gremlin
// 返回列表
g.V().toList()
// 返回下一个
g.V().next()
g.V().next(5) // 返回5个
// 执行遍历(不返回结果)
g.addV('person').property('name', 'Tom').iterate()
6.2 hasNext()/tryNext() #
gremlin
// 检查是否有结果
g.V().has('name', 'Tom').hasNext()
// 尝试获取下一个(返回Optional)
g.V().has('name', 'Tom').tryNext()
七、修改步骤 #
7.1 addV() - 添加顶点 #
gremlin
// 添加顶点
g.addV('person').property('name', 'Tom')
// 批量添加
g.addV('person').property('name', 'Tom').
addV('person').property('name', 'Jerry')
7.2 addE() - 添加边 #
gremlin
// 添加边
g.addE('knows').from(V('1')).to(V('2'))
// 从遍历添加
g.V('1').addE('knows').to(V('2'))
7.3 property() - 设置属性 #
gremlin
// 设置属性
g.V('1').property('age', 30)
// 设置多值属性
g.V('1').property(list, 'phone', '123-456-7890')
7.4 drop() - 删除 #
gremlin
// 删除顶点
g.V('1').drop()
// 删除边
g.E('e1').drop()
// 删除属性
g.V('1').properties('age').drop()
八、重复遍历 #
8.1 repeat() - 重复遍历 #
gremlin
// 重复N次
g.V('1').repeat(out()).times(3)
// 直到条件
g.V('1').repeat(out()).until(has('name', 'Jerry'))
// 发射中间结果
g.V('1').repeat(out()).emit().times(3)
// 条件发射
g.V('1').repeat(out()).emit(has('status', 'active')).times(3)
8.2 until()/emit() - 条件控制 #
gremlin
// until - 终止条件
g.V('1').repeat(out()).until(outE().count().is(0))
// emit - 发射条件
g.V('1').repeat(out()).emit().until(has('name', 'Jerry'))
// emit在repeat前
g.V('1').emit().repeat(out()).times(3)
九、合并操作 #
9.1 union() - 合并 #
gremlin
// 合并多个遍历
g.V('1').union(
out('knows'),
out('follows')
)
// 合并结果
g.V('1').union(
out('knows'),
in('knows')
).dedup()
9.2 coalesce() - 首选非空 #
gremlin
// 返回第一个非空结果
g.V().coalesce(
values('nickname'),
values('name'),
constant('Unknown')
)
9.3 choose() - 条件选择 #
gremlin
// if-else
g.V().choose(
has('age', gt(30)),
values('name'),
constant('Young')
)
// switch-case
g.V().choose(values('status'))
.option('active', values('name'))
.option('inactive', constant('Disabled'))
.option(none, constant('Unknown'))
十、实用技巧 #
10.1 性能优化 #
gremlin
// 使用标签过滤
g.V().hasLabel('person').has('name', 'Tom')
// 使用limit限制结果
g.V().limit(100)
// 使用索引属性
g.V().has('userId', 'user_001')
// 避免全图扫描
g.V().hasLabel('person') // 好
g.V() // 避免
10.2 调试技巧 #
gremlin
// 查看中间结果
g.V().hasLabel('person').as('persons').
out('knows').as('friends').
select('persons', 'friends')
// 计算中间数量
g.V().hasLabel('person').count().as('personCount').
select('personCount')
// 使用profile分析
g.V().hasLabel('person').out('knows').profile()
十一、总结 #
Gremlin语法要点:
| 类别 | 步骤 | 说明 |
|---|---|---|
| 源步骤 | V(), E() | 遍历起点 |
| 过滤步骤 | has(), filter(), where() | 过滤数据 |
| 变换步骤 | out(), in(), map() | 变换数据 |
| 聚合步骤 | count(), group(), order() | 聚合数据 |
| 终端步骤 | toList(), next(), iterate() | 执行遍历 |
下一步,让我们学习遍历操作!
最后更新:2026-03-27