属性 #

一、属性概述 #

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) 过滤属性

最佳实践:

  1. 使用合适的命名规范
  2. 选择正确的数据类型
  3. 合理使用属性基数
  4. 避免过大的属性值
  5. 使用属性索引加速查询

下一步,让我们学习标签与类型!

最后更新:2026-03-27