04 · 推理引擎集成实现

目标:用 Apache Jena 加载 OWL 本体,实现推理(等价识别、维度层级展开、指标推导)。

1. Maven 依赖

<dependency>
    <groupId>org.apache.jena</groupId>
    <artifactId>apache-jena-libs</artifactId>
    <version>4.10.0</version>
</dependency>

2. 加载本体 + 启用推理

import org.apache.jena.ontology.*;
import org.apache.jena.query.*;

// OWL 推理模型(含 RDFS + OWL 规则推理)
OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_RULE_INF);
model.read("metric.ttl");   // 加载 Turtle 本体

OWL_MEM_RULE_INF 支持传递性(TransitiveProperty)、等价类(equivalentClass)等推理规则,MVP 够用。

3. 三个核心推理场景

3.1 等价识别(成交额 ≡ GMV)

String sparql = """
    PREFIX : <http://example.org/metric-ontology#>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    SELECT ?m WHERE { ?m owl:equivalentClass :GMV }
    """;
try (QueryExecution qe = QueryExecutionFactory.create(sparql, model)) {
    ResultSet rs = qe.execSelect();
    // 结果:成交额、销售额
}

3.2 维度层级展开(华东区 ⊇ 各省)

String sparql = """
    PREFIX : <http://example.org/metric-ontology#>
    SELECT ?region WHERE { ?region :partOf :华东区 }
    """;
// 结果:上海、江苏、浙江、安徽、福建、江西、山东(partOf 是 TransitiveProperty,自动递归)

3.3 指标推导(客单价 = GMV ÷ 订单数)

String sparql = """
    PREFIX : <http://example.org/metric-ontology#>
    SELECT ?component WHERE { :客单价 :composedOf ?component }
    """;
// 结果:GMV、订单数

4. 封装成服务(Spring Bean)

@Service
public class OntologyService {
    private final OntModel model;

    public OntologyService() {
        this.model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_RULE_INF);
        this.model.read("metric.ttl");   // 路径从配置读
    }

    /** 等价指标识别:传入"成交额",返回规范指标 GMV */
    public String resolveEquivalentMetric(String rawMetric) {
        // SPARQL 查 owl:equivalentClass,返回等价的本体概念
    }

    /** 维度层级展开:传入"华东区",返回省份列表 */
    public List<String> expandRegion(String region) {
        // SPARQL 查 :partOf,返回所有子成员
    }

    /** 指标推导:传入"客单价",返回组成指标列表 */
    public List<String> getComponents(String metric) {
        // SPARQL 查 :composedOf
    }

    /** 查映射:返回指标映射的物理字段 */
    public String getMappedColumn(String metric) {
        // SPARQL 查 :mapsToColumn
    }
}

5. 关键注意