1 Reply Latest reply on Feb 11, 2011 11:37 PM by alwu-Oracle

    How to do a count(*) with Jena Adapter?

    kevinpauli
      Hi, I am trying to do a count(*). I know it's not part of the SPARQL 1.0 standard, but it is supported in ARQ, and presumably by the Jena Adapter too then?

      Other examples I have been able to find do an iteration over the resultset to get a count, but that is not acceptable since I have millions of triples. In my tests it took 15 seconds to return the count by using iteration. Oracle Semantic is advertised as scaling to "hundreds of millions of triples"; so how do I do a simple count(*) aggregation?

      Below is the code I tried. It works with a regular jena default model, returning the expected result of "2", but the result is empty if I use the Oracle Jena adapter.


      import oracle.spatial.rdf.client.jena.ModelOracleSem;
      import oracle.spatial.rdf.client.jena.Oracle;

      import com.hp.hpl.jena.graph.Node;
      import com.hp.hpl.jena.graph.Triple;
      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;

      public class OracleJenaAdapterCountTest {

           public static void main(String[] args) throws Exception {
                String szJdbcURL = "jdbc:oracle:thin:@dragon12:1521:mydb";
                String szUser = "mydb";
                String szPasswd = "yeahright";
                String szModelName = "kp_mydb_model";
                Oracle oracle = new Oracle(szJdbcURL, szUser, szPasswd);
                Model model = ModelOracleSem.createOracleSemModel(oracle,
                szModelName);
                // this one works
                //Model model = ModelFactory.createDefaultModel();

                model.getGraph().add(
                          Triple.create(Node.createURI("http://example.com/John"),
                                    Node.createURI("http://example.com/fatherOf"),
                                    Node.createURI("http://example.com/Mary")));
                model.getGraph().add(
                          Triple.create(Node.createURI("http://example.com/John"),
                                    Node.createURI("http://example.com/fatherOf"),
                                    Node.createURI("http://example.com/Bob")));

                Query query = QueryFactory
                          .create("select (count(*) as ?count) {?f <http://example.com/fatherOf> ?k .}");
                QueryExecution qexec = QueryExecutionFactory.create(query, model);
                ResultSet results = qexec.execSelect();
                ResultSetFormatter.out(System.out, results, query);

                model.close();
                oracle.dispose();
           }
      }
        • 1. Re: How to do a count(*) with Jena Adapter?
          alwu-Oracle
          Hi,

          Which version of Jena/Jena Adapter are you using?

          I am a bit surprised that your query did not throw out an exception. I need to set Syntax.syntaxARQ
          in the query creation, as follows. (Without it, I got com.hp.hpl.jena.query.QueryParseException when
          executing the same code.)

          Query query = QueryFactory
          .create("select (count(*) as ?count) {?f <http://example.com/fatherOf> ?k .}",
          Syntax.syntaxARQ);

          Once I have the above change, I did get the right count.
          ---------
          | count |
          =========
          | 2 |
          ---------

          The above query is not the most efficient one in terms of getting the count. Because we have to select out all projection and send the data from the database to the Java client. If you are using the latest Jena Adapter, you can use the count_only which will instruct the underlying query to return the count directly from the database.

          Query query = QueryFactory
          .create("PREFIX ORACLE_SEM_FS_NS: <http://oracle.com/semtech#count_only> select ?count {?f <http://example.com/fatherOf> ?k .}",
          Syntax.syntaxARQ);

          Cheers,

          Zhe Wu