属性 #
一、属性概述 #
1.1 什么是属性 #
属性是附加在顶点或边上的键值对,用于存储实体的详细信息。
text
属性组成:
├── 键(Key):属性名称
├── 值(Value):属性值
└── 元属性(Meta Property):属性的属性(可选)
1.2 属性特点 #
text
属性特点:
├── 键值对形式
├── 支持多种数据类型
├── 支持多值属性
├── 可附加在顶点或边上
└── 支持属性元数据
1.3 属性结构 #
text
顶点属性示例:
┌─────────────────────────┐
│ Person │
│─────────────────────────│
│ name: "Tom" │ ← 单值属性
│ age: 30 │ ← 数值属性
│ emails: [ │ ← 多值属性
│ "tom@test.com",
│ "tom@work.com"
│ ]
│ address: { │ ← 复杂属性(存储为Map)
│ city: "New York",
│ zip: "10001"
│ }
└─────────────────────────┘
二、数据类型 #
2.1 基本数据类型 #
| 类型 | 说明 | 示例 |
|---|---|---|
| String | 字符串 | “Tom” |
| Integer | 整数 | 30 |
| Long | 长整数 | 1234567890L |
| Float | 单精度浮点 | 3.14f |
| Double | 双精度浮点 | 3.14159265359 |
| Boolean | 布尔值 | true |
| Date | 日期时间 | 2024-01-01T00:00:00 |
2.2 复杂数据类型 #
text
复杂数据类型:
├── List(列表)
│ └── 有序集合,允许重复
├── Set(集合)
│ └── 无序集合,不允许重复
└── Map(映射)
└── 键值对集合
2.3 类型示例 #
gremlin
// 字符串
g.V('1').property('name', 'Tom')
// 整数
g.V('1').property('age', 30)
// 长整数
g.V('1').property('timestamp', 1234567890L)
// 浮点数
g.V('1').property('score', 95.5)
// 布尔值
g.V('1').property('active', true)
// 日期时间
g.V('1').property('createdAt', datetime())
三、属性基数 #
3.1 基数类型 #
text
属性基数:
├── single(单值)
│ └── 只能有一个值,新值覆盖旧值
├── set(集合)
│ └── 可以有多个值,自动去重
└── list(列表)
└── 可以有多个值,允许重复
3.2 单值属性(Single) #
gremlin
// 创建单值属性
g.V('1').property(single, 'name', 'Tom')
// 更新会覆盖
g.V('1').property(single, 'name', 'Jerry') // 覆盖Tom
// 查询
g.V('1').values('name') // 返回: Jerry
3.3 集合属性(Set) #
gremlin
// 创建集合属性
g.V('1').property(set, 'tag', 'important')
g.V('1').property(set, 'tag', 'urgent')
g.V('1').property(set, 'tag', 'important') // 重复值会被忽略
// 查询
g.V('1').values('tag') // 返回: ['important', 'urgent']
3.4 列表属性(List) #
gremlin
// 创建列表属性
g.V('1').property(list, 'phone', '123-456-7890')
g.V('1').property(list, 'phone', '098-765-4321')
g.V('1').property(list, 'phone', '123-456-7890') // 允许重复
// 查询
g.V('1').values('phone') // 返回: ['123-456-7890', '098-765-4321', '123-456-7890']
四、属性操作 #
4.1 添加属性 #
gremlin
// 添加单个属性
g.V('1').property('name', 'Tom')
// 添加多个属性
g.V('1').
property('name', 'Tom').
property('age', 30).
property('email', 'tom@test.com')
// 使用Map添加属性
g.V('1').property(map, ['name': 'Tom', 'age': 30])
// 添加带元数据的属性
g.V('1').property('name', 'Tom').
property('name_verified', true)
4.2 查询属性 #
gremlin
// 获取单个属性值
g.V('1').values('name')
// 获取多个属性值
g.V('1').values('name', 'age')
// 获取所有属性值
g.V('1').values()
// 获取属性键
g.V('1').keys()
// 获取属性映射
g.V('1').valueMap()
// 获取属性映射(包含所有值)
g.V('1').valueMap(true)
// 获取属性对象
g.V('1').properties()
// 获取指定属性对象
g.V('1').properties('name')
4.3 更新属性 #
gremlin
// 更新属性值
g.V('1').property('age', 31)
// 条件更新
g.V('1').property('age', 31).has('age', 30)
// 增量更新
g.V('1').property('age', values('age').math('+1'))
// 使用sack更新
g.V('1').sack(assign).by('age').
sack(math('_+1')).
property('age', sack())
4.4 删除属性 #
gremlin
// 删除单个属性
g.V('1').properties('age').drop()
// 删除多个属性
g.V('1').properties('age', 'email').drop()
// 删除所有属性
g.V('1').properties().drop()
// 删除多值属性中的特定值
g.V('1').properties('phone').hasValue('old-phone').drop()
五、属性过滤 #
5.1 基本过滤 #
gremlin
// 精确匹配
g.V().has('name', 'Tom')
// 不等于
g.V().has('name', neq('Tom'))
// 存在属性
g.V().has('name')
g.V().has('name', within('Tom', 'Jerry'))
// 不存在属性
g.V().hasNot('name')
5.2 数值过滤 #
gremlin
// 大于
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', inside(20, 40))
// 区间外
g.V().has('age', outside(20, 40))
5.3 字符串过滤 #
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'))
5.4 复合过滤 #
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'))
六、属性聚合 #
6.1 分组 #
gremlin
// 按属性分组
g.V().group().by('status')
// 按属性分组计数
g.V().groupCount().by('status')
// 按属性分组聚合
g.V().group().
by('status').
by('age', mean())
// 多级分组
g.V().group().
by('status').
by(group().by('department'))
6.2 统计 #
gremlin
// 计数
g.V().count()
// 求和
g.V().values('age').sum()
// 平均值
g.V().values('age').mean()
// 最大值
g.V().values('age').max()
// 最小值
g.V().values('age').min()
// 统计信息
g.V().values('age').fold().
project('count', 'sum', 'mean', 'min', 'max').
by(count(local)).
by(sum(local)).
by(mean(local)).
by(min(local)).
by(max(local))
6.3 排序 #
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)
七、属性投影 #
7.1 选择属性 #
gremlin
// 选择单个属性
g.V().values('name')
// 选择多个属性
g.V().valueMap('name', 'age')
// 使用project
g.V().project('name', 'age', 'email').
by('name').
by('age').
by('email')
// 使用select
g.V().as('v').values('name').as('name').
select('v').values('age').as('age').
select('name', 'age')
7.2 计算属性 #
gremlin
// 使用map计算
g.V().map(values('firstName') + ' ' + values('lastName'))
// 使用project计算
g.V().project('name', 'age', 'ageGroup').
by('name').
by('age').
by(values('age').choose(
lt(30), constant('young'),
lt(50), constant('middle'),
constant('senior')
))
// 使用math计算
g.V().values('price').math('_ * 1.1') // 加10%
八、属性最佳实践 #
8.1 命名规范 #
text
属性命名规范:
├── 使用小驼峰或下划线
├── 保持命名一致性
├── 使用描述性名称
├── 避免保留字
└── 考虑查询便利性
示例:
text
推荐:
├── firstName, lastName
├── created_at, updated_at
├── isActive, hasPermission
└── totalPrice, discountRate
避免:
├── fn, ln(缩写不清晰)
├── name1, name2(无意义数字)
└── property, value(太通用)
8.2 类型选择 #
text
类型选择建议:
├── 使用合适的数据类型
├── 日期使用Date类型
├── 数值区分Integer和Double
├── 布尔值使用Boolean
└── 避免字符串存储结构化数据
8.3 基数选择 #
text
基数选择建议:
├── 单值属性:大多数情况
├── 集合属性:标签、分类等
└── 列表属性:有序集合、历史记录
8.4 性能优化 #
text
性能优化建议:
├── 避免过大的属性值
├── 合理使用多值属性
├── 使用属性索引
├── 避免过多属性
└── 考虑属性查询模式
九、实际应用示例 #
9.1 用户属性 #
gremlin
// 创建用户属性
g.addV('user').
property('userId', 'user_001').
property('username', 'tom_hanks').
property('email', 'tom@example.com').
property('age', 30).
property('active', true).
property(list, 'roles', 'user').
property(list, 'roles', 'admin').
property('createdAt', datetime()).
property('lastLogin', datetime())
// 查询活跃用户
g.V().hasLabel('user').
has('active', true).
has('lastLogin', gt(someDate))
// 更新最后登录时间
g.V().has('userId', 'user_001').
property('lastLogin', datetime())
9.2 产品属性 #
gremlin
// 创建产品属性
g.addV('product').
property('productId', 'prod_001').
property('name', 'iPhone 15').
property('description', 'Latest iPhone').
property('price', 999.99).
property('stock', 100).
property('category', 'Electronics').
property(set, 'tags', 'phone').
property(set, 'tags', 'apple').
property(set, 'tags', 'smartphone').
property('createdAt', datetime())
// 查询产品
g.V().hasLabel('product').
has('category', 'Electronics').
has('price', inside(500, 1500)).
has('tags', containing('apple'))
// 更新库存
g.V().has('productId', 'prod_001').
property('stock', values('stock').math('_ - 1'))
9.3 文档属性 #
gremlin
// 创建文档属性
g.addV('document').
property('docId', 'doc_001').
property('title', 'Neptune Guide').
property('content', '...').
property('author', 'Tom').
property('status', 'draft').
property('version', 1).
property('createdAt', datetime()).
property('updatedAt', datetime())
// 查询文档
g.V().hasLabel('document').
has('status', 'published').
order().by('updatedAt', desc).
limit(10)
// 更新文档状态
g.V().has('docId', 'doc_001').
property('status', 'published').
property('updatedAt', datetime()).
property('version', values('version').math('_ + 1'))
十、总结 #
属性操作要点:
| 操作 | Gremlin语法 | 说明 |
|---|---|---|
| 添加 | property(key, value) | 添加属性 |
| 查询 | values(key) | 查询属性值 |
| 更新 | property(key, value) | 更新属性 |
| 删除 | properties(key).drop() | 删除属性 |
| 过滤 | has(key, value) | 过滤属性 |
最佳实践:
- 使用合适的命名规范
- 选择正确的数据类型
- 合理使用属性基数
- 避免过大的属性值
- 使用属性索引加速查询
下一步,让我们学习标签与类型!
最后更新:2026-03-27