# 04 · 关键文件

> 三个核心文件：本体骨架（metric.ttl）、指标配置（metrics.yaml）、Maven 依赖（pom.xml）。本体管推理，配置管数据。

## 1. metric.ttl（本体骨架，只放推理关系）

```turtle
@prefix : <http://example.org/metric#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

# ===== 概念类体系 =====
:Metric a owl:Class .
:AtomicMetric   a owl:Class ; rdfs:subClassOf :Metric .
:DerivedMetric  a owl:Class ; rdfs:subClassOf :Metric .
:CompositeMetric a owl:Class ; rdfs:subClassOf :Metric .
:Dimension a owl:Class .
:RegionDimension a owl:Class ; rdfs:subClassOf :Dimension .

# ===== 推理关系 =====
:partOf a owl:ObjectProperty, owl:TransitiveProperty .   # 维度层级（传递）
:composedOf a owl:ObjectProperty .                        # 复合指标组成
:derivedFrom a owl:ObjectProperty .                       # 派生指标来源

# ===== 指标实例（只声明类型和推理关系，口径/映射在配置里）=====
:GMV a :AtomicMetric .
:订单数 a :AtomicMetric .
:客单价 a :CompositeMetric ; :composedOf :GMV, :订单数 .

# ===== 等价公理（业务术语对齐，这是推理关系）=====
:成交额 a :AtomicMetric ; owl:equivalentClass :GMV .
:销售额 a :AtomicMetric ; owl:equivalentClass :GMV .

# ===== 维度层级公理（这是推理关系）=====
:上海 :partOf :华东区 .  :江苏 :partOf :华东区 .  :浙江 :partOf :华东区 .
:安徽 :partOf :华东区 .  :福建 :partOf :华东区 .  :江西 :partOf :华东区 .
:山东 :partOf :华东区 .
:华东区 :partOf :中国 .
```

## 2. metrics.yaml（指标配置，放口径和映射）

```yaml
metrics:
  GMV:
    type: atomic            # atomic / composite
    table: dwd_bill         # 账单表
    column: bill_amount     # 度量字段
    calc_expr: "SUM(bill_amount)"
    filter_expr: "status='paid' AND refunded=false"   # 口径
    required_filters: ["status='paid'", "refunded=false"]  # 口径校验用

  订单数:
    type: atomic
    table: dwd_bill
    column: bill_count
    calc_expr: "SUM(bill_count)"
    filter_expr: "status='paid'"
    required_filters: ["status='paid'"]

  客单价:
    type: composite         # 复合指标
    expression: "{GMV} / {订单数}"   # 组成关系在本体 :composedOf
```

## 3. pom.xml（Maven 依赖）

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>metric-ontology-query</artifactId>
    <version>0.1.0</version>
    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <!-- Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 本体推理：Apache Jena -->
        <dependency>
            <groupId>org.apache.jena</groupId>
            <artifactId>apache-jena-libs</artifactId>
            <version>4.10.0</version>
            <type>pom</type>
        </dependency>

        <!-- 配置解析：SnakeYAML（Spring Boot 内置，可直接用） -->

        <!-- MaxCompute：复用已有封装（odps-sdk-core 0.59.0-public） -->
        <dependency>
            <groupId>com.aliyun.odps</groupId>
            <artifactId>odps-sdk-core</artifactId>
            <version>0.59.0-public</version>
        </dependency>
    </dependencies>
</project>
```

## 4. application.yml

```yaml
server:
  port: 8080

ontology:
  file: classpath:ontology/metric.ttl    # 本体文件
  config: classpath:config/metrics.yaml  # 指标配置

llm:
  base-url: https://api.deepseek.com
  api-key: ${DEEPSEEK_API_KEY}           # 从环境变量读，不硬编码
  model: deepseek-chat

maxcompute:
  endpoint: ${MAXCOMPUTE_ENDPOINT}
  access-id: ${MAXCOMPUTE_ACCESS_ID}
  access-key: ${MAXCOMPUTE_ACCESS_KEY}
  project: ${MAXCOMPUTE_PROJECT}
```

## 5. 关键设计要点

- **本体只放推理关系**：等价（equivalentClass）、层级（partOf）、派生（composedOf）在本体；口径（filter_expr）、映射（table/column）在配置。这是"本体管推理、配置管数据"的落地。
- **口径双重表达**：`filter_expr` 用于 SQL 生成，`required_filters` 用于生成后校验（双保险）。
- **敏感信息走环境变量**：API Key、MaxCompute 凭据都不硬编码，从环境变量注入。
- **新增指标的流程**：① 加本体实例（如 `:新指标 a :AtomicMetric` + 等价/派生关系）→ ② 加配置（口径、映射）→ ③ 重启生效。无需改代码。
