过滤与转换 #
一、过滤操作概述 #
1.1 什么是过滤 #
过滤是从遍历流中选择满足特定条件的元素的操作。
text
过滤操作分类:
├── 属性过滤:has(), hasNot()
├── 条件过滤:filter(), where()
├── 标签过滤:hasLabel()
├── 去重:dedup()
└── 逻辑过滤:and(), or(), not()
二、属性过滤 #
2.1 has() - 基本过滤 #
gremlin
// 存在属性
g.V().has('name')
// 精确匹配
g.V().has('name', '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))
g.V().has('age', outside(20, 40))
// 列表匹配
g.V().has('name', within('Tom', 'Jerry', 'Mike'))
g.V().has('name', without('Tom', 'Jerry'))
2.2 字符串过滤 #
gremlin
// 包含子串
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'))
g.V().has('email', regex('.*@example\\.com'))
2.3 多属性过滤 #
gremlin
// 多条件AND
g.V().has('name', 'Tom').has('age', gt(25))
// 使用has()链式
g.V().has('name', 'Tom').has('age', gt(25)).has('status', 'active')
// 使用and()
g.V().and(
has('name', 'Tom'),
has('age', gt(25))
)
2.4 hasNot() - 属性不存在 #
gremlin
// 属性不存在
g.V().hasNot('email')
// 等价于
g.V().not(has('email'))
// 组合使用
g.V().has('name').hasNot('email')
三、标签过滤 #
3.1 hasLabel() #
gremlin
// 单标签
g.V().hasLabel('person')
// 多标签(OR关系)
g.V().hasLabel('person', 'employee', 'manager')
// 边标签
g.E().hasLabel('knows', 'follows')
// 组合过滤
g.V().hasLabel('person').has('status', 'active')
3.2 hasKey()/hasValue() #
gremlin
// 属性键存在
g.V().hasKey('name', 'email')
// 属性值存在
g.V().hasValue('Tom', 'Jerry')
// 组合使用
g.V().properties().hasKey('name')
四、条件过滤 #
4.1 filter() - 自定义过滤 #
gremlin
// 使用filter
g.V().filter(outE().count().is(gt(0)))
// 复杂条件
g.V().filter(
and(
outE().count().is(gt(0)),
inE().count().is(gt(0))
)
)
// 使用Lambda(注意性能)
g.V().filter { it.get().property('name').orElse('').startsWith('T') }
4.2 where() - 条件过滤 #
gremlin
// 简单条件
g.V().where(outE().count().is(gt(5)))
// 使用标记比较
g.V().as('a').out('knows').as('b').
where('a', neq('b'))
// 按属性比较
g.V().as('a').out('knows').as('b').
where('a', neq('b')).by('name')
// 复杂条件
g.V().as('a').out('knows').as('b').
where('a', lt('b')).by('age')
4.3 where(P) - 谓词过滤 #
gremlin
// 使用谓词
g.V().where(values('age').is(gt(25)))
// 组合谓词
g.V().where(values('age').is(inside(20, 40)))
// 使用within
g.V().where(values('name').is(within('Tom', 'Jerry')))
五、去重操作 #
5.1 dedup() - 基本去重 #
gremlin
// 简单去重
g.V().out('knows').dedup()
// 去重后计数
g.V().out('knows').dedup().count()
// 去重后取值
g.V().out('knows').dedup().values('name')
5.2 dedup().by() - 按属性去重 #
gremlin
// 按属性去重
g.V().dedup().by('name')
// 按计算值去重
g.V().dedup().by(outE().count())
// 按标记去重
g.V().as('a').out('knows').as('b').dedup('a', 'b')
5.3 dedup()与repeat() #
gremlin
// 重复遍历中去重
g.V('1').repeat(out().dedup()).times(3)
// 使用simplePath避免环路
g.V('1').repeat(out().simplePath()).times(3)
六、逻辑操作 #
6.1 and() - 与操作 #
gremlin
// AND条件
g.V().and(
has('age', gt(25)),
has('name', startingWith('T'))
)
// 多条件AND
g.V().and(
has('status', 'active'),
has('age', inside(20, 40)),
has('name', startingWith('T'))
)
// 遍历AND
g.V().and(
outE('knows'),
outE('follows')
)
6.2 or() - 或操作 #
gremlin
// OR条件
g.V().or(
has('name', 'Tom'),
has('name', 'Jerry')
)
// 多条件OR
g.V().or(
has('status', 'active'),
has('status', 'pending'),
has('age', gt(50))
)
// 遍历OR
g.V().or(
out('knows'),
out('follows')
)
6.3 not() - 非操作 #
gremlin
// NOT条件
g.V().not(has('status', 'inactive'))
// 复杂NOT
g.V().not(
or(
has('status', 'inactive'),
has('age', lt(18))
)
)
// NOT遍历
g.V().not(out('knows'))
七、转换操作概述 #
7.1 什么是转换 #
转换是将遍历流中的元素映射为其他形式的操作。
text
转换操作分类:
├── 映射:map(), flatMap()
├── 选择:select(), project()
├── 值提取:values(), valueMap()
├── 合并:union(), coalesce()
└── 计算:math(), sack()
八、映射操作 #
8.1 map() - 一对一映射 #
gremlin
// 映射属性
g.V().map(values('name'))
// 映射计算值
g.V().map(outE().count())
// 映射对象
g.V().map(project('name', 'age').by('name').by('age'))
// 复杂映射
g.V().map(
coalesce(values('nickname'), values('name'))
)
8.2 flatMap() - 一对多映射 #
gremlin
// 展开遍历结果
g.V().flatMap(out('knows'))
// 展开属性值
g.V().flatMap(values('name', 'email'))
// 展开列表
g.V().flatMap(values('tags'))
// 复杂flatMap
g.V().flatMap(
out('knows').out('knows')
)
8.3 map vs flatMap #
gremlin
// map - 返回单个结果
g.V().map(values('name')) // 每个顶点返回一个name
// flatMap - 返回多个结果
g.V().flatMap(values('name', 'email')) // 每个顶点可能返回多个值
九、选择操作 #
9.1 select() - 选择标记 #
gremlin
// 选择单个标记
g.V().as('a').out('knows').as('b').select('a')
// 选择多个标记
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)
9.2 project() - 投影 #
gremlin
// 简单投影
g.V().project('name', 'age').by('name').by('age')
// 复杂投影
g.V().project('name', 'friendCount', 'status').
by('name').
by(out('knows').count()).
by(coalesce(values('status'), constant('unknown')))
// 嵌套投影
g.V().project('person', 'friends').
by(valueMap('name', 'age')).
by(out('knows').values('name').fold())
9.3 values() - 提取值 #
gremlin
// 单个属性
g.V().values('name')
// 多个属性
g.V().values('name', 'age')
// 所有属性
g.V().values()
// 属性对象
g.V().properties('name')
9.4 valueMap() - 属性映射 #
gremlin
// 属性映射
g.V().valueMap()
// 指定属性
g.V().valueMap('name', 'age')
// 包含ID和标签
g.V().valueMap(true)
// 展开单值
g.V().valueMap().by(unfold())
十、合并操作 #
10.1 union() - 合并遍历 #
gremlin
// 合并结果
g.V('1').union(
out('knows'),
out('follows')
)
// 合并不同类型
g.V('1').union(
out('knows').hasLabel('person'),
out('follows').hasLabel('person')
).dedup()
// 合并计算
g.V('1').union(
out('knows').count(),
in('knows').count()
).sum()
10.2 coalesce() - 首选非空 #
gremlin
// 返回第一个非空结果
g.V().coalesce(
values('nickname'),
values('name'),
constant('Unknown')
)
// 遍历合并
g.V('1').coalesce(
out('knows'),
out('follows'),
constant([])
)
// 属性合并
g.V().coalesce(
has('email').values('email'),
has('phone').values('phone'),
constant('No contact')
)
10.3 merge() - 合并结果 #
gremlin
// 合并多个结果
g.V('1').merge(
out('knows'),
in('knows')
).dedup()
十一、计算操作 #
11.1 math() - 数学计算 #
gremlin
// 简单计算
g.V().values('price').math('_ * 1.1') // 加10%
// 使用标记
g.V().as('a').values('price').as('p').
select('a').values('discount').as('d').
math('p * (1 - d)')
// 复杂计算
g.V().values('price').math('_ * 0.9 + 10')
11.2 sack() - 背包操作 #
gremlin
// 初始化背包
g.withSack(0).V('1').repeat(
outE().sack(sum).by('weight').inV()
).times(3).sack()
// 条件背包
g.withSack(0).V().
sack(sum).by(constant(1)).
repeat(out()).times(3).
sack()
// 背包过滤
g.withSack(0).V('1').repeat(
outE().sack(sum).by('weight').inV()
).emit().sack().is(lt(100))
十二、条件转换 #
12.1 choose() - 条件选择 #
gremlin
// if-else
g.V().choose(
has('age', gt(30)),
values('name'),
constant('Young')
)
// 嵌套choose
g.V().choose(
has('status', 'active'),
values('name'),
choose(
has('status', 'pending'),
constant('Pending'),
constant('Inactive')
)
)
12.2 option() - 多选项 #
gremlin
// switch-case
g.V().choose(values('status'))
.option('active', values('name'))
.option('pending', constant('Pending'))
.option('inactive', constant('Inactive'))
.option(none, constant('Unknown'))
12.3 constant() - 常量 #
gremlin
// 返回常量
g.V().constant('Hello')
// 条件常量
g.V().choose(
has('status', 'active'),
constant(true),
constant(false)
)
// 默认值
g.V().coalesce(values('email'), constant('No email'))
十三、实际应用示例 #
13.1 数据清洗 #
gremlin
// 清理空值
g.V().hasLabel('person').
project('name', 'email', 'phone').
by('name').
by(coalesce(values('email'), constant('N/A'))).
by(coalesce(values('phone'), constant('N/A')))
// 格式化输出
g.V().hasLabel('person').
map(
project('fullName', 'contact').
by(concat(values('firstName'), constant(' '), values('lastName'))).
by(coalesce(values('email'), values('phone'), constant('No contact')))
)
13.2 数据转换 #
gremlin
// 类型转换
g.V().hasLabel('product').
project('name', 'price', 'priceWithTax').
by('name').
by('price').
by(values('price').math('_ * 1.1'))
// 状态转换
g.V().hasLabel('order').
project('orderId', 'status', 'statusText').
by('orderId').
by('status').
by(choose(values('status'))
.option('pending', constant('待处理'))
.option('processing', constant('处理中'))
.option('completed', constant('已完成'))
.option(none, constant('未知')))
13.3 数据聚合 #
gremlin
// 分组统计
g.V().hasLabel('person').
group().
by('department').
by(project('count', 'avgAge', 'names').
by(count()).
by(values('age').mean()).
by(values('name').fold())
)
// 多维度聚合
g.V().hasLabel('order').
group().
by('status').
by(project('count', 'totalAmount').
by(count()).
by(values('amount').sum())
)
十四、总结 #
过滤操作要点:
| 操作 | 语法 | 说明 |
|---|---|---|
| 属性过滤 | has() | 按属性过滤 |
| 条件过滤 | filter(), where() | 自定义条件 |
| 去重 | dedup() | 去除重复 |
| 逻辑操作 | and(), or(), not() | 逻辑组合 |
转换操作要点:
| 操作 | 语法 | 说明 |
|---|---|---|
| 映射 | map(), flatMap() | 元素映射 |
| 选择 | select(), project() | 选择数据 |
| 合并 | union(), coalesce() | 合并结果 |
| 计算 | math(), sack() | 数学计算 |
下一步,让我们学习SPARQL基础!
最后更新:2026-03-27