Jena基于OWL的默认推理查询

目录

一些背景

数据导入

普通查询

推理查询


一些背景

       通过Jena的API,我们可以将RDF的.nt文件导入到对应TDB存储中,然后使用相关API进行三元组的查询,但是这时候的查询只能对存储中存在的三元组数据进行查询,是不包含推理的。

       这篇文章关于Jena的推理讲的比较清楚。 

       这篇文章是基础,主要介绍RDF/RDFS/OWL之间的关系和前世今生,只有了解这些,才能更好的理解Jena的推理。

       简单来说,RDF是实际三元组数据的存储的描述规范,但是这只能是数据组织的规范,不能描述数据,因此又出现了RDFS,RDFS我们可以简单理解成描述语言;简而言之,可以简单理解为:RDF是数据库里实际数据,RDFS是数据库表结构说明。但是RDFS对于关系的表达能力还是不足,后来又出现了OWL,OWL是RDFS的补充和完善。

       OWL文件也是我们常说的本体描述文件,对三元组的本体、关系进行描述说明的文件。 通过这个本体描述,结合API我们就可以进行推理查询。 

       第一篇关于推理的文章中实际上是有关于推理的演示的,但是它是基于Fuseki来实现的,通过Fuseki配置相关配置文件,开启推理器,指定TDB存储位置,然后进行查询,就能推理查询出实际不存在的三元组数据。 

       我重点记录是的通过API代码方式进行查询的样例。

数据导入

    public static void loadRdfData(){
        String directory = "D:\\jena\\test" ;
        String ntFile = "D:\\kg_demo_movie.nt";
        Dataset dataset = TDBFactory.createDataset(directory);
        Model model = dataset.getNamedModel("kgMovie");
        RDFDataMgr.read(model,ntFile);
        checkModel(dataset);
        dataset.close();
    }
    public static void checkModel(Dataset dataset){
        Iterator<String> names = dataset.listNames();
        String           name  = null;
        while (names.hasNext())
        {
            name = names.next();
            System.out.println(name);
        }
    }
    public static void exampleQuery(Model model){
        String sparqlQueryString = "PREFIX : <http://www.kgdemo.com#> \n" + "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \n" + "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n" + "SELECT ?x ?p ?o WHERE {\n" + "?x :movieTitle '功夫'.\n" + "?x ?p ?o.\n" + "}" ;
        Query query = QueryFactory.create(sparqlQueryString) ;
        QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
        try {
            ResultSet    results = qexec.execSelect() ;
            for ( ; results.hasNext() ; )
            {
                QuerySolution soln = results.nextSolution() ;
                System.out.println(soln.get("x")+"   "+soln.get("p")+"   "+soln.get("o"));
            }

        } finally { qexec.close() ; }
    }

       其中exampleQuery是一个公共方法,封装了一个query查询,下面的普通查询和推理查询都会用到。 推理查询相比普通查询,主要是开启了推理机。

普通查询

    public static void sampleSearch(){
        String directory = "D:\\jena\\test" ;
        Dataset dataset = TDBFactory.createDataset(directory);

        Model model = dataset.getNamedModel("kgMovie");
        exampleQuery(model);

        dataset.close();
    }

       查询结果如下:

        这个结果正是RDF中的数据一一对应。 

推理查询

    public static void reasonersSearch(){
        String directory = "D:\\jena\\test" ;
        String ttlFile = "D:\\movie_owl.ttl";
        Dataset dataset = TDBFactory.createDataset(directory);

        //RDF数据Model
        Model dataModel = dataset.getNamedModel("kgMovie");
        //owl本体描述schema
        Model schema = RDFDataMgr.loadModel(ttlFile, Lang.TTL);
        //添加推理机
        Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
        reasoner = reasoner.bindSchema(schema);
        //创建模型
        InfModel infmodel = ModelFactory.createInfModel(reasoner, dataModel);
        //查询
        exampleQuery(infmodel);
        dataset.close();
    }

       结果如下:

        其中hasActor是通过推理查询出来的,因为存在Person--hasActedIn-Movie这样的三元组数据,然后OWL的描述规则中hasActedIn和hasActor的关系inverseOf,如下:

###  http://www.kgdemo.com#hasActedIn
:hasActedIn rdf:type owl:ObjectProperty ;
            owl:inverseOf :hasActor ;
            rdfs:domain :Person ;
            rdfs:range :Movie .


###  http://www.kgdemo.com#hasActor
:hasActor rdf:type owl:ObjectProperty ;
          rdfs:domain :Movie ;
          rdfs:range :Person .


###  http://www.kgdemo.com#hasGenre
:hasGenre rdf:type owl:ObjectProperty ;
          rdfs:domain :Movie ;
          rdfs:range :Genre .

       所以,通过推理查询也可以将电影拥有的演员信息查询出来。 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值