第一个 Ontology:创建 ObjectType 和 RelationType
Ontology(本体)是 coomia-dip 的核心抽象。如果说传统数据库用"表"来描述数据,那么 coomia-dip 用"本体"来描述世界。ObjectType 类似于面向对象编程中的"类",RelationType 则描述类与类之间的关系。这种建模方式让数据不仅有结构,还有语义——机器能够"理解"数据之间的关联。
“系列:S12 开发者教程 · 第 2 篇 | 难度:入门 | 阅读时间:15 分钟
第一个 Ontology:创建 ObjectType 和 RelationType
#引言
Ontology(本体)是 coomia-dip 的核心抽象。如果说传统数据库用"表"来描述数据,那么 coomia-dip 用"本体"来描述世界。ObjectType 类似于面向对象编程中的"类",RelationType 则描述类与类之间的关系。这种建模方式让数据不仅有结构,还有语义——机器能够"理解"数据之间的关联。
本教程将带你深入了解 Ontology 的核心概念,并通过 Python SDK 创建你的第一个完整的本体模型。
#核心概念
#ObjectType 是什么?
ObjectType 是 coomia-dip 中描述业务实体的元数据定义。它类似于数据库中的表定义(Schema)或面向对象编程中的类(Class)。每个 ObjectType 定义了一组属性(Properties),每个属性有类型、约束和描述。
在 Palantir Foundry 中,这对应的就是 Object Type。coomia-dip 保持了与 Foundry 相同的语义模型,但使用开源技术栈实现。
from ontology_sdk import OntoPlatform
platform = OntoPlatform(
control_plane_url="localhost:50051",
data_plane_url="localhost:50052"
)
# 创建一个 ObjectType
employee_type = platform.ontology.create_object_type(
name="Employee",
display_name="员工",
description="企业员工实体",
properties={
"employee_id": {
"type": "string",
"required": True,
"description": "员工编号",
"constraints": {"pattern": "^EMP-[0-9]{6}$"}
},
"name": {
"type": "string",
"required": True,
"description": "员工姓名"
},
"email": {
"type": "string",
"required": True,
"constraints": {"format": "email", "unique": True}
},
"title": {"type": "string", "description": "职位"},
"level": {
"type": "integer",
"constraints": {"min": 1, "max": 15}
},
"hire_date": {"type": "date", "required": True},
"salary": {
"type": "decimal",
"constraints": {"min": 0, "precision": 2}
},
"is_active": {"type": "boolean", "default": True},
"skills": {"type": "array", "items_type": "string"}
},
primary_key="employee_id"
)
print(f"Created: {employee_type.name} (rid={employee_type.rid})")
#属性类型系统
coomia-dip 支持 14 种内置属性类型:
| 类型 | 说明 | 示例值 |
|---|---|---|
string | 字符串 | "张三" |
integer | 32位整数 | 42 |
long | 64位整数 | 1234567890123 |
decimal | 精确小数 | 99999.99 |
double | 浮点数 | 3.14159 |
boolean | 布尔值 | true |
date | 日期 | "2024-01-01" |
datetime | 日期时间 | "2024-01-01T12:00:00Z" |
timestamp | 毫秒时间戳 | 1704067200000 |
enum | 枚举 | "active" |
array | 数组 | ["java", "python"] |
map | 键值对 | {"region": "asia"} |
geo_point | 地理坐标 | [121.47, 31.23] |
attachment | 附件引用 | "ri.attachment.xxx" |
每种类型都支持约束条件(constraints),如字符串的 pattern、数值的 min/max、数组的 max_length 等。
#RelationType 是什么?
RelationType 定义两个 ObjectType 之间的语义关系。与传统数据库的外键不同,RelationType 携带语义信息,并且可以拥有自己的属性。
支持三种基数(Cardinality):
- ONE_TO_ONE:一对一,如 Employee → Badge
- ONE_TO_MANY:一对多,如 Department → Employee
- MANY_TO_MANY:多对多,如 Employee → Project
# 创建 Department ObjectType
dept_type = platform.ontology.create_object_type(
name="Department",
display_name="部门",
properties={
"dept_id": {"type": "string", "required": True},
"name": {"type": "string", "required": True},
"code": {"type": "string", "constraints": {"unique": True}},
"budget": {"type": "decimal"},
},
primary_key="dept_id"
)
# 创建关系:员工 → 部门(多对一)
belongs_to = platform.ontology.create_relation_type(
name="belongs_to",
display_name="属于",
source_type="Employee",
target_type="Department",
cardinality="MANY_TO_ONE",
properties={
"joined_at": {"type": "date"},
"role_in_dept": {"type": "string"}
}
)
print(f"Relation: {belongs_to.source_type} --[{belongs_to.name}]--> {belongs_to.target_type}")
#完整建模示例:企业组织管理
让我们构建一个完整的企业组织管理 Ontology,包含三个 ObjectType 和四个 RelationType。
#业务场景
- 公司有多个部门,部门之间有上下级关系
- 每个员工属于一个部门
- 公司有多个项目,每个项目由一个部门负责
- 员工可以参与多个项目
#创建所有 ObjectType
# Project ObjectType
project_type = platform.ontology.create_object_type(
name="Project",
display_name="项目",
properties={
"project_id": {"type": "string", "required": True},
"name": {"type": "string", "required": True},
"status": {
"type": "enum",
"values": ["planning", "in_progress", "on_hold", "completed", "cancelled"],
"default": "planning"
},
"priority": {
"type": "enum",
"values": ["low", "medium", "high", "critical"]
},
"budget": {"type": "decimal"},
"start_date": {"type": "date"},
"end_date": {"type": "date"},
"tags": {"type": "array", "items_type": "string"}
},
primary_key="project_id"
)
#创建所有 RelationType
# 员工参与项目(多对多)
participates_in = platform.ontology.create_relation_type(
name="participates_in",
display_name="参与",
source_type="Employee",
target_type="Project",
cardinality="MANY_TO_MANY",
properties={
"role": {
"type": "enum",
"values": ["owner", "member", "reviewer", "observer"]
},
"allocation_pct": {
"type": "integer",
"constraints": {"min": 0, "max": 100}
}
}
)
# 部门负责项目(一对多)
owns_project = platform.ontology.create_relation_type(
name="owns_project",
display_name="负责",
source_type="Department",
target_type="Project",
cardinality="ONE_TO_MANY"
)
# 部门上下级(自引用)
parent_dept = platform.ontology.create_relation_type(
name="parent_department",
display_name="上级部门",
source_type="Department",
target_type="Department",
cardinality="MANY_TO_ONE"
)
#查看 Ontology 图谱
# 列出所有 ObjectType
for ot in platform.ontology.list_object_types():
print(f"ObjectType: {ot.name} ({ot.display_name})")
for p in ot.properties:
req = " [必填]" if p.required else ""
print(f" - {p.name}: {p.type}{req}")
# 列出所有关系
for rt in platform.ontology.list_relation_types():
print(f"Relation: {rt.source_type} --[{rt.name}]--> {rt.target_type} ({rt.cardinality})")
# 导出 Mermaid 图
graph = platform.ontology.export_graph(format="mermaid")
print(graph)
输出的关系图:
Employee --[belongs_to]--> Department (MANY_TO_ONE)
Employee --[participates_in]--> Project (MANY_TO_MANY)
Department --[owns_project]--> Project (ONE_TO_MANY)
Department --[parent_department]--> Department (MANY_TO_ONE)
#动态修改 Ontology
coomia-dip 的一大优势是支持运行时动态修改 Ontology,无需停机迁移。
#添加属性
platform.ontology.update_object_type(
name="Employee",
add_properties={
"phone": {"type": "string", "description": "手机号"},
"avatar_url": {"type": "string", "description": "头像"}
}
)
#修改属性
platform.ontology.update_object_type(
name="Employee",
update_properties={
"skills": {"description": "技能标签列表(已更新)"}
}
)
#删除属性
platform.ontology.update_object_type(
name="Employee",
remove_properties=["avatar_url"]
)
#Ontology 版本管理
coomia-dip 通过 Nessie 集成实现 Ontology 的版本管理,类似 Git 的分支模型:
# 查看 Ontology 变更历史
history = platform.ontology.get_history(object_type="Employee")
for entry in history:
print(f" {entry.timestamp}: {entry.change_type} by {entry.user}")
# 创建 Ontology 分支(用于测试变更)
branch = platform.ontology.create_branch("feature/add-address-type")
# 在分支上修改
platform.ontology.create_object_type(
name="Address",
branch="feature/add-address-type",
properties={...}
)
# 合并回主线
platform.ontology.merge_branch("feature/add-address-type")
#与 Palantir Foundry 的对比
| 特性 | Palantir Foundry | coomia-dip |
|---|---|---|
| ObjectType 定义 | Web UI + API | SDK + API + YAML |
| RelationType | Link Type | RelationType(等价) |
| 属性约束 | 有限 | 丰富(正则、范围、唯一) |
| 动态修改 | 支持 | 支持 |
| 版本管理 | 有 | 有(基于 Nessie) |
| API 协议 | REST | gRPC(内部)+ REST(外部) |
| 代价 | $$$$ | 开源免费 |
#最佳实践
- 命名规范:ObjectType 用 PascalCase,属性用 snake_case,RelationType 用动词短语
- 单一职责:每个 ObjectType 描述一个业务概念
- 适度属性:5-15 个属性为佳
- 明确关系:用 RelationType 而非 JSON 嵌套
- 善用约束:pattern、min/max、unique 提升数据质量
- 文档化:为每个属性添加 description
#常见问题
#Q: ObjectType 可以继承吗?
目前 coomia-dip 不支持 ObjectType 继承。推荐使用组合模式——创建共享属性的 ObjectType 并通过 RelationType 关联。
#Q: 属性可以删除吗?
可以。删除属性后,已有数据中该属性的值会被保留(标记为 deprecated),但新写入的数据不再包含该属性。
#Q: 最多支持多少个 ObjectType?
理论上没有限制。生产环境中我们测试过 1000+ ObjectType 的场景,性能表现良好。
#下一步
- 第一条数据 — 在 Ontology 上写入和查询实体
- 第一个 Action — 定义业务操作
- OQL 查询指南 — 复杂关系查询
#总结
本教程介绍了 coomia-dip 的核心概念——Ontology,包括 ObjectType(对象类型)和 RelationType(关系类型)。通过一个企业组织管理的实例,我们学习了如何定义类型、属性、约束和关系,以及如何进行动态修改和版本管理。Ontology 是 coomia-dip 区别于传统数据平台的核心能力,它让数据从"行和列"升级为"有语义的知识图谱"。
本文是 coomia-dip 开发者教程系列的第 2 篇。 项目地址:https://github.com/coomia-dip/coomia-dip↗ | 许可证:Apache License 2.0