Jena TDB 101 Java API without Assembler

时间:2023-03-09 16:56:24
Jena TDB 101 Java API without Assembler

Update on 2015/05/12

ongoing tutorials site on https://github.com/zhoujiagen/semanticWebTutorialUsingJena

废话

/**
前几天的面试,是一个组织研究生团队开展分布式计算应用的面试。在该面试中,被虐的很惨,在这里整理一下一些重要的反馈:

(1)什么是本体、语义Web?有没有什么应用市场?

第一遍回答的支离破碎的,之后面试官是在看不下去,诱导性的说举个例子吧,才回答出概念taxonomy、概念关系和关系推理等内容。

至于应用市场直接回答没有考虑过,面试官提醒可以在搜索引擎中应用,哎,专业性都受到严重的质疑。

(2) 目前做过的简单Java开发已经有廉价的工具优雅的替代了。

这部分不想多说,连我自己都认为是这样,我也不想当个“廉价的”J2EE开发工程师。因简历上hadoop、hbase前面我写的是了解,只问了一下有没有装过hadoop,确实是装过0.x版本的伪分布式模式的。

这一系列语义网的随笔确实是为体现专业性而写的,之前OntoABAC原型系统中用到的技术是可以演示毕业论文中的论点的,但完全无法达到研究前沿和应用级别的要求。

据我所知,语义网的前沿是在其层次体系结构中上层的proof和trust,而应用级别又要求满足低成本、大数据量和结合计算架构的开发。

长城不是一夜间堆完的,革命尚未成功,自己仍需努力;多暴露自己的不足、多问几个为什么,尽力完善专业性知识。

*/

前言

RDF中数据,尤其是实例断言的数据量很大时,该怎么处理?采用老而弥坚的关系型数据库?还是使用其他模型的存储?

Jena本身支持SDB(http://jena.apache.org/documentation/sdb/),支持RDF数据在关系型数据库中的存储,但其页面中也提出不建议使用这种方式。有兴趣的可以去看Oracle的语义技术开发者指南。

本文以一个示例展示如何在TDB中以编程方式实现RDF数据的存储和访问,不涉及assembler。

内容

1 数据!

2 创建Dataset、加载数据

3 查询数据

4 遗留问题

1 数据!

exploration.owl - 导入FOAF.rdf,添加了部分概念、实例、关系和一个SWRL规则

<?xml version="1.0"?>

<!DOCTYPE rdf:RDF [
    <!ENTITY foaf "http://xmlns.com/foaf/0.1/" >
    <!ENTITY owl "http://www.w3.org/2002/07/owl#" >
    <!ENTITY swrl "http://www.w3.org/2003/11/swrl#" >
    <!ENTITY swrlb "http://www.w3.org/2003/11/swrlb#" >
    <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
    <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
    <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
]>

<rdf:RDF xmlns="http://www.jena.application.com/exploration#"
     xml:base="http://www.jena.application.com/exploration"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:swrl="http://www.w3.org/2003/11/swrl#"
     xmlns:foaf="http://xmlns.com/foaf/0.1/"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:swrlb="http://www.w3.org/2003/11/swrlb#"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <owl:Ontology rdf:about="http://www.jena.application.com/exploration">
        <owl:versionIRI rdf:resource="http://www.jena.application.com/exploration/1.0"/>
        <owl:imports rdf:resource="http://xmlns.com/foaf/0.1/"/>
    </owl:Ontology>

    <!--
    ///////////////////////////////////////////////////////////////////////////////////////
    //
    // Data properties
    //
    ///////////////////////////////////////////////////////////////////////////////////////
     -->

    <!-- http://www.jena.application.com/exploration#mbox -->

    <owl:DatatypeProperty rdf:about="http://www.jena.application.com/exploration#mbox"/>

    <!--
    ///////////////////////////////////////////////////////////////////////////////////////
    //
    // Classes
    //
    ///////////////////////////////////////////////////////////////////////////////////////
     -->

    <!-- http://www.jena.application.com/exploration#GmailPerson -->

    <owl:Class rdf:about="http://www.jena.application.com/exploration#GmailPerson"/>

    <!--
    ///////////////////////////////////////////////////////////////////////////////////////
    //
    // Individuals
    //
    ///////////////////////////////////////////////////////////////////////////////////////
     -->

    <!-- http://www.jena.application.com/exploration#Ontology -->

    <owl:NamedIndividual rdf:about="http://www.jena.application.com/exploration#Ontology">
        <rdf:type rdf:resource="http://schema.org/Person"/>
        <foaf:name rdf:datatype="&xsd;string">I. M. Ontology</foaf:name>
        <rdfs:seeAlso rdf:datatype="&xsd;string">http://ont.com
</rdfs:seeAlso>
        <mbox rdf:datatype="&xsd;string">onto@gmail.com</mbox>
    </owl:NamedIndividual>

    <!-- http://www.jena.application.com/exploration#Reasoner -->

    <owl:NamedIndividual rdf:about="http://www.jena.application.com/exploration#Reasoner">
        <rdf:type rdf:resource="http://schema.org/Person"/>
        <foaf:name rdf:datatype="&xsd;string">Ican Reason</foaf:name>
        <rdfs:seeAlso rdf:datatype="&xsd;string">http://reasoner.com</rdfs:seeAlso>
        <mbox rdf:datatype="&xsd;string">reason@hotmail.com</mbox>
    </owl:NamedIndividual>

    <!-- http://www.jena.application.com/exploration#Statement -->

    <owl:NamedIndividual rdf:about="http://www.jena.application.com/exploration#Statement">
        <rdf:type rdf:resource="http://schema.org/Person"/>
        <foaf:name rdf:datatype="&xsd;string">Makea Statement</foaf:name>
        <rdfs:seeAlso rdf:datatype="&xsd;string">http://statement.com</rdfs:seeAlso>
        <mbox rdf:datatype="&xsd;string">mstatement@gmail.com</mbox>
    </owl:NamedIndividual>

    <!-- http://www.jena.application.com/exploration#me -->

    <owl:NamedIndividual rdf:about="http://www.jena.application.com/exploration#me">
        <rdf:type rdf:resource="http://schema.org/Person"/>
        <foaf:name rdf:datatype="&xsd;string">Zhou Jia-Gen</foaf:name>
        <mbox rdf:datatype="&xsd;string">zhoujiagen@gmail.com</mbox>
        <foaf:knows rdf:resource="http://www.jena.application.com/exploration#Ontology"/>
        <foaf:knows rdf:resource="http://www.jena.application.com/exploration#Reasoner"/>
        <foaf:knows rdf:resource="http://www.jena.application.com/exploration#Statement"/>
    </owl:NamedIndividual>

    <!--
    ///////////////////////////////////////////////////////////////////////////////////////
    //
    // Rules
    //
    ///////////////////////////////////////////////////////////////////////////////////////
     -->

    <rdf:Description rdf:about="urn:swrl#p">
        <rdf:type rdf:resource="&swrl;Variable"/>
    </rdf:Description>
    <rdf:Description rdf:about="urn:swrl#m">
        <rdf:type rdf:resource="&swrl;Variable"/>
    </rdf:Description>
    <rdf:Description>
        <rdf:type rdf:resource="&swrl;Imp"/>
        <swrl:body>
            <rdf:Description>
                <rdf:type rdf:resource="&swrl;AtomList"/>
                <rdf:first>
                    <rdf:Description>
                        <rdf:type rdf:resource="&swrl;ClassAtom"/>
                        <swrl:classPredicate rdf:resource="&foaf;Person"/>
                        <swrl:argument1 rdf:resource="urn:swrl#p"/>
                    </rdf:Description>
                </rdf:first>
                <rdf:rest>
                    <rdf:Description>
                        <rdf:type rdf:resource="&swrl;AtomList"/>
                        <rdf:rest>
                            <rdf:Description>
                                <rdf:type rdf:resource="&swrl;AtomList"/>
                                <rdf:rest rdf:resource="&rdf;nil"/>
                                <rdf:first>
                                    <rdf:Description>
                                        <rdf:type rdf:resource="&swrl;BuiltinAtom"/>
                                        <swrl:builtin rdf:resource="&swrlb;contains"/>
                                        <swrl:arguments>
                                            <rdf:Description>
                                                <rdf:type rdf:resource="&rdf;List"/>
                                                <rdf:first rdf:resource="urn:swrl#m"/>
                                                <rdf:rest>
                                                    <rdf:Description>
                                                        <rdf:type rdf:resource="&rdf;List"/>
                                                        <rdf:first>@gmail.com</rdf:first>
                                                        <rdf:rest rdf:resource="&rdf;nil"/>
                                                    </rdf:Description>
                                                </rdf:rest>
                                            </rdf:Description>
                                        </swrl:arguments>
                                    </rdf:Description>
                                </rdf:first>
                            </rdf:Description>
                        </rdf:rest>
                        <rdf:first>
                            <rdf:Description>
                                <rdf:type rdf:resource="&swrl;DatavaluedPropertyAtom"/>
                                <swrl:propertyPredicate rdf:resource="http://www.jena.application.com/exploration#mbox"/>
                                <swrl:argument2 rdf:resource="urn:swrl#m"/>
                                <swrl:argument1 rdf:resource="urn:swrl#p"/>
                            </rdf:Description>
                        </rdf:first>
                    </rdf:Description>
                </rdf:rest>
            </rdf:Description>
        </swrl:body>
        <swrl:head>
            <rdf:Description>
                <rdf:type rdf:resource="&swrl;AtomList"/>
                <rdf:rest rdf:resource="&rdf;nil"/>
                <rdf:first>
                    <rdf:Description>
                        <rdf:type rdf:resource="&swrl;ClassAtom"/>
                        <swrl:classPredicate rdf:resource="http://www.jena.application.com/exploration#GmailPerson"/>
                        <swrl:argument1 rdf:resource="urn:swrl#p"/>
                    </rdf:Description>
                </rdf:first>
            </rdf:Description>
        </swrl:head>
    </rdf:Description>
</rdf:RDF>

<!-- Generated by the OWL API (version 3.4.2) http://owlapi.sourceforge.net -->

graph.owl - NoSQL精粹中文版封面图的RDF表示

<?xml version="1.0"?>

<!DOCTYPE rdf:RDF [
    <!ENTITY graph "http://www.nosql.com/graph#" >
    <!ENTITY owl "http://www.w3.org/2002/07/owl#" >
    <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
    <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
    <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
]>

<rdf:RDF xmlns="http://www.nosql.com/graph#"
     xml:base="http://www.nosql.com/graph"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:graph="http://www.nosql.com/graph#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <owl:Ontology rdf:about="http://www.nosql.com/graph">
        <owl:versionIRI rdf:resource="http://www.nosql.com/graph/1.0"/>
    </owl:Ontology>

    <!--
    ///////////////////////////////////////////////////////////////////////////////////////
    //
    // Object Properties
    //
    ///////////////////////////////////////////////////////////////////////////////////////
     -->

    <!-- http://www.nosql.com/graph#author -->

    <owl:ObjectProperty rdf:about="&graph;author">
        <rdfs:domain rdf:resource="&graph;Book"/>
        <rdfs:range rdf:resource="&graph;Person"/>
    </owl:ObjectProperty>

    <!-- http://www.nosql.com/graph#category -->

    <owl:ObjectProperty rdf:about="&graph;category">
        <rdfs:domain rdf:resource="&graph;Book"/>
        <rdfs:range rdf:resource="&graph;BookCategory"/>
    </owl:ObjectProperty>

    <!-- http://www.nosql.com/graph#employee -->

    <owl:ObjectProperty rdf:about="&graph;employee">
        <rdfs:range rdf:resource="&graph;Company"/>
        <rdfs:domain rdf:resource="&graph;Person"/>
    </owl:ObjectProperty>

    <!-- http://www.nosql.com/graph#friend -->

    <owl:ObjectProperty rdf:about="&graph;friend">
        <rdf:type rdf:resource="&owl;SymmetricProperty"/>
        <rdfs:domain rdf:resource="&graph;Person"/>
        <rdfs:range rdf:resource="&graph;Person"/>
    </owl:ObjectProperty>

    <!-- http://www.nosql.com/graph#like -->

    <owl:ObjectProperty rdf:about="&graph;like">
        <rdfs:range rdf:resource="&graph;Book"/>
        <rdfs:domain rdf:resource="&graph;Person"/>
    </owl:ObjectProperty>

    <!--
    ///////////////////////////////////////////////////////////////////////////////////////
    //
    // Classes
    //
    ///////////////////////////////////////////////////////////////////////////////////////
     -->

    <!-- http://www.nosql.com/graph#Book -->

    <owl:Class rdf:about="&graph;Book"/>

    <!-- http://www.nosql.com/graph#BookCategory -->

    <owl:Class rdf:about="&graph;BookCategory"/>

    <!-- http://www.nosql.com/graph#Company -->

    <owl:Class rdf:about="&graph;Company"/>

    <!-- http://www.nosql.com/graph#Person -->

    <owl:Class rdf:about="&graph;Person"/>

    <!--
    ///////////////////////////////////////////////////////////////////////////////////////
    //
    // Individuals
    //
    ///////////////////////////////////////////////////////////////////////////////////////
     -->

    <!-- http://www.nosql.com/graph#Anna -->

    <owl:NamedIndividual rdf:about="&graph;Anna">
        <rdf:type rdf:resource="&graph;Person"/>
        <friend rdf:resource="&graph;Barbara"/>
        <employee rdf:resource="&graph;BigCo"/>
        <like rdf:resource="&graph;Refactoring"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#Barbara -->

    <owl:NamedIndividual rdf:about="&graph;Barbara">
        <rdf:type rdf:resource="&graph;Person"/>
        <employee rdf:resource="&graph;BigCo"/>
        <friend rdf:resource="&graph;Carol"/>
        <friend rdf:resource="&graph;Elizabeth"/>
        <like rdf:resource="&graph;NoSQL_Distilled"/>
        <like rdf:resource="&graph;Refactoring"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#BigCo -->

    <owl:NamedIndividual rdf:about="&graph;BigCo">
        <rdf:type rdf:resource="&graph;Company"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#Carol -->

    <owl:NamedIndividual rdf:about="&graph;Carol">
        <rdf:type rdf:resource="&graph;Person"/>
        <employee rdf:resource="&graph;BigCo"/>
        <friend rdf:resource="&graph;Dawn"/>
        <like rdf:resource="&graph;NoSQL_Distilled"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#Database_Refactoring -->

    <owl:NamedIndividual rdf:about="&graph;Database_Refactoring">
        <rdf:type rdf:resource="&graph;Book"/>
        <category rdf:resource="&graph;Databases"/>
        <author rdf:resource="&graph;Pramod"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#Databases -->

    <owl:NamedIndividual rdf:about="&graph;Databases">
        <rdf:type rdf:resource="&graph;BookCategory"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#Dawn -->

    <owl:NamedIndividual rdf:about="&graph;Dawn">
        <rdf:type rdf:resource="&graph;Person"/>
        <friend rdf:resource="&graph;Jill"/>
        <like rdf:resource="&graph;NoSQL_Distilled"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#Elizabeth -->

    <owl:NamedIndividual rdf:about="&graph;Elizabeth">
        <rdf:type rdf:resource="&graph;Person"/>
        <friend rdf:resource="&graph;Jill"/>
        <like rdf:resource="&graph;NoSQL_Distilled"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#Jill -->

    <owl:NamedIndividual rdf:about="&graph;Jill">
        <rdf:type rdf:resource="&graph;Person"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#Martin -->

    <owl:NamedIndividual rdf:about="&graph;Martin">
        <rdf:type rdf:resource="&graph;Person"/>
        <friend rdf:resource="&graph;Pramod"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#NoSQL_Distilled -->

    <owl:NamedIndividual rdf:about="&graph;NoSQL_Distilled">
        <rdf:type rdf:resource="&graph;Book"/>
        <category rdf:resource="&graph;Databases"/>
        <author rdf:resource="&graph;Martin"/>
        <author rdf:resource="&graph;Pramod"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#Pramod -->

    <owl:NamedIndividual rdf:about="&graph;Pramod">
        <rdf:type rdf:resource="&graph;Person"/>
    </owl:NamedIndividual>

    <!-- http://www.nosql.com/graph#Refactoring -->

    <owl:NamedIndividual rdf:about="&graph;Refactoring">
        <rdf:type rdf:resource="&graph;Book"/>
        <author rdf:resource="&graph;Martin"/>
    </owl:NamedIndividual>
</rdf:RDF>

<!-- Generated by the OWL API (version 3.4.2) http://owlapi.sourceforge.net -->

2 创建Dataset、加载数据

参考了二进制发布包中的实例代码,首先在./Store/DB1目录下创建数据集,该数据集的默认模型加载exploration.owl中数据,已命名模型加载graph.owl,加载是在TDB事务中完成的。

package tdb.examples;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Iterator;

import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.ReadWrite;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.tdb.TDBFactory;

public class ExTDB1 {
    public static void main(String... argv) throws FileNotFoundException {
        // 如果目录为空,则创建TDB索引文件和节点表
        // If a directory is empty, the TDB files for indexes and node table are created.

        // Direct way: Make a TDB-back Jena model in the named directory.
        String directory = "./Store/DB1";
        // 使用TDBFactory创建TDB数据集
        Dataset dataset = TDBFactory.createDataset(directory);

        // ... do work ...
        // 开始事务
        dataset.begin(ReadWrite.WRITE);
        Model model = ModelFactory.createDefaultModel();
        String nosqlBase = "http://www.nosql.com/graph";
        model.read(new FileInputStream("./rdf/nosql/graph.owl"), nosqlBase);
        dataset.addNamedModel(nosqlBase, model);// 命名模型
        dataset.commit();

        dataset.begin(ReadWrite.WRITE);
        String base = "http://www.jena.application.com/exploration";
        Model model2 = dataset.getDefaultModel();// 默认模型
        model2.read(new FileInputStream("./rdf/application/exploration.owl"), base);
        dataset.commit();

        dataset.begin(ReadWrite.READ);
        System.out.println("list dataset's Model names:");
        Iterator<String> nameIter = dataset.listNames();
        while (nameIter.hasNext()) {
            System.out.println(nameIter.next());
        }
        // Model model3 = dataset.getNamedModel(base);
        Model model3 = dataset.getDefaultModel();
        System.out.println(model3.getGraph().toString());
        dataset.end();

        // 关闭数据集
        dataset.close();
    }
}

生成数据集文件结构(各文件含义暂不清楚):

Jena TDB 101 Java API without Assembler

 3 查询数据

以SPARQL查询支持数据集中数据查询,下面的代码分别在数据集中的两个模型中执行查询

package tdb.examples;

import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.tdb.TDBFactory;

public class ExTDB4 {
    public static void main(String... argv) {
        // Direct way: Make a TDB-back Jena model in the named directory.
        String directory = "./Store/DB1";
        Dataset dataset = TDBFactory.createDataset(directory);

        // Potentially expensive query.
        String sparqlQueryString = "SELECT (count(*) AS ?count) { ?s ?p ?o }";
        // See http://incubator.apache.org/jena/documentation/query/app_api.html

        // 使用QueryFactory创建SPARQL查询
        Query query = QueryFactory.create(sparqlQueryString);
        Model defaultModel = dataset.getDefaultModel();
        String nosqlBase = "http://www.nosql.com/graph";
        Model namedModel = dataset.getNamedModel(nosqlBase);

        // query defaultModel
        QueryExecution qexec = QueryExecutionFactory.create(query, defaultModel);
        ResultSet results = qexec.execSelect();
        ResultSetFormatter.out(results);
        qexec.close();

        // query namedModel
        QueryExecution qexec2 = QueryExecutionFactory.create(query, namedModel);
        ResultSet results2 = qexec2.execSelect();
        ResultSetFormatter.out(results2);
        qexec2.close();

        dataset.close();
    }
}

有关Jena ARQ (SPARQL)可以参见 https://jena.apache.org/documentation/query/index.html,在Protege中编辑SPARQL查询是极好的:

Jena TDB 101 Java API without Assembler

也可以参考下面的代码片段执行SPARQL SELECT查询,其中包括了基本模型和推理后模型中的查询

package arq;

import static util.Constants.BOUNDARY;
import static util.Constants.NEWLINE;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.rdf.model.InfModel;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.reasoner.Reasoner;
import com.hp.hpl.jena.reasoner.ReasonerRegistry;

/**
 * <ul>
 * <li>Author: zhoujg | Date: 2014-4-5 下午10:14:49</li>
 * <li>Description: Jena ARQ演示</li>
 * </ul>
 */
public class JenaARQMain {
    static Model model = null;
    static InfModel infModel = null;

    static void loadModel() {
        model = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM);
        String nosqlBase = "http://www.nosql.com/graph";
        try {
            model.read(new FileInputStream("./rdf/nosql/graph.owl"), nosqlBase);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
        reasoner = reasoner.bindSchema(model);// tbox
        infModel = ModelFactory.createInfModel(reasoner, model);// abox
    }

    public static void main(String[] args) {
        loadModel();

        // single value - base model
        // queryFriend(model, "Pramod");// Martin
        // queryFriend(model, "Martin");// null

        // single value - inferred model
        // queryFriend(infModel, "Pramod");// Martin
        // queryFriend(infModel, "Martin");// Pramod

        // multiple value - base model
        // queryFriend(model, "Jill");// Elizabeth Dawn

        // multiple value - inferred model
        // queryFriend(infModel, "Barbara");// Anna Elizabeth Carol

        // format resultset
        queryFriendFormattedResultset(infModel, "Barbara");
    }

    static void sparqlFormatedResult(Model model, String query, String valueLabel) {
        Query q = QueryFactory.create(query);
        QueryExecution qexec = QueryExecutionFactory.create(q, model);
        System.out.println("Plan to run SPARQL query: ");
        System.out.println(BOUNDARY);
        System.out.println(query);
        System.out.println(BOUNDARY);
        ResultSet rs = qexec.execSelect();
        ResultSetFormatter.out(System.out, rs);
        // ResultSetFormatter.outputAsXML(rs);// XML格式
        // ResultSetFormatter.outputAsJSON(rs);// JSON格式
        qexec.close();
    }

    static void sparql(Model model, String query, String valueLabel) {
        Query q = QueryFactory.create(query);
        QueryExecution qexec = QueryExecutionFactory.create(q, model);
        System.out.println("Plan to run SPARQL query: ");
        System.out.println(BOUNDARY);
        System.out.println(query);
        System.out.println(BOUNDARY);
        ResultSet rs = qexec.execSelect();
        while (rs.hasNext()) {
            QuerySolution qs = rs.nextSolution();
            RDFNode name = qs.get(valueLabel);
            if (name != null) {
                System.out.println("Found friend " + name.toString());
            } else {
                System.out.println("No friend found!");
            }
        }
        qexec.close();
    }

    static void queryFriend(Model model, String name) {
        StringBuilder sb = generateSPARQLPREFIX();
        sb.append("SELECT DISTINCT ?friend WHERE { ?friend nosql:friend nosql:").append(name).append(" }").append(NEWLINE);
        sparql(model, sb.toString(), "?friend");
    }

    static void queryFriendFormattedResultset(Model model, String name) {
        StringBuilder sb = generateSPARQLPREFIX();
        sb.append("SELECT DISTINCT ?friend WHERE { ?friend nosql:friend nosql:").append(name).append(" }").append(NEWLINE);
        sparqlFormatedResult(model, sb.toString(), "?friend");
    }

    static StringBuilder generateSPARQLPREFIX() {
        StringBuilder sb = new StringBuilder();
        sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>").append(NEWLINE).append("PREFIX owl: <http://www.w3.org/2002/07/owl#>")
                .append(NEWLINE).append("PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>").append(NEWLINE)
                .append("PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>").append(NEWLINE).append("PREFIX foaf: <http://xmlns.com/foaf/0.1/>")
                .append(NEWLINE).append("PREFIX myfoaf: <http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#>").append(NEWLINE)
                .append("PREFIX nosql: <http://www.nosql.com/graph#>").append(NEWLINE);
        return sb;
    }
}

4 遗留问题

能支持多大的存储数量级? - SERIOUSLY, I am working on this. 2015/07/01 updated

影响查询时间的因素有哪些?

数据集中文件有什么含义?