如何在GraphDB规则集中定义高级自定义规则,为50岁以上人员新增推导事实
问题:GraphDB自定义年龄筛选规则实现方案
图数据库中存储了若干人员实体,关联有birthDate、name等谓词属性。需要编写自定义规则,为年龄超过50岁的人员新增相关事实,实现该需求需完成两个步骤:计算年龄、筛选符合年龄条件的人员。
对应的SPARQL查询参考写法如下:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX drl: <http://...> SELECT DISTINCT ?person ?age WHERE { ?person rdf:type drl:Person. ?person drl:Person.birthDate/drl:value ?birthDate; BIND(year(now()) - year(?birthDate) as ?age) FILTER (?age > 50) }
GraphDB推理规则定义语法如下:
规则定义的语法如下:
Id: <rule_name> <premises> <optional_constraints> ------------------------------- <consequences> <optional_constraints>
待解答的疑问点:
- 是否可以在
<premises>或<optional_constraints>块内使用BIND和FILTER关键字?目前猜测该方案不可行,是否有其他方式可以实现这类规则? - SPARQL SPIN函数和魔法谓词不支持在GraphDB中使用,有没有替代方案?
回答
*GraphDB的自定义蕴涵规则不支持在premises或constraints块中直接使用SPARQL的BIND、FILTER关键字,规则语法仅支持三元组模式匹配和内置的基础约束算子,无法直接执行函数计算和复杂条件过滤。
你可以选择以下三种替代方案实现需求:
- 方案1:预计算物化年龄属性
先定期执行你给出的SPARQL查询,将计算得到的drl:age属性直接写入实体属性中,之后编写规则直接匹配该属性即可,示例规则如下:
上述规则中的数值比较属于GraphDB规则支持的内置约束,可以直接写在premises后的可选约束位置。Id: tag_elderly_person ?person rdf:type drl:Person . ?person drl:age ?age . ?age > 50 ------------------------------- ?person drl:isElderly "true"^^xsd:boolean . - 方案2:用SPARQL更新替代规则推理
如果预计算物化的方案不符合实时性要求,可以用SPARQL的INSERT语句代替规则推理,通过定时任务或触发式执行直接生成需要的派生事实,示例语句如下:PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX drl: <http://...> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> INSERT { ?person drl:isElderly "true"^^xsd:boolean . } WHERE { ?person rdf:type drl:Person. ?person drl:Person.birthDate/drl:value ?birthDate; BIND(year(now()) - year(?birthDate) as ?age) FILTER (?age > 50) FILTER NOT EXISTS {?person drl:isElderly "true"^^xsd:boolean} } - 方案3:自定义Java函数扩展
GraphDB支持自定义Java开发的SPARQL函数,你可以把年龄计算逻辑封装成自定义函数,之后在SPARQL查询或者更新语句中直接调用,不需要依赖SPIN或者魔法谓词。
内容的提问来源于stack exchange,提问作者Paweł Goławski
相关产品推荐
相关产品推荐

