5 Ответы Последний ответ: 08.08.2008 14:29, автор: alwu-Oracle

    Running a SPARQL query across all models

    637657
      Is there a concise way of running a SPARQL query against all models in the database (or at least all models owned by a db user) via the Oracle Jena Adapter? Do I have to manually find all models, add them to a GraphOracleSem, and pass a composite model (from the graph) to a QueryFactory.create() method or is there a simpler way like something synonymous to DatasetStore.create() that would pass back the entire dataset?

      Thanks
        • 1. Re: Running a SPARQL query across all models
          alwu-Oracle
          Do you want to run the same query against each and every individual model and then concatenate the results?

          Or, you want that query to be run against a merged graph of all models?

          How many models are we talking about btw?
          • 2. Re: Running a SPARQL query across all models
            637657
            I want to run the query against a merged graph of all the models.
            I see you can do this by attaching an Attachment containing the list of all model names to a graph. I could be dealing with several models. I really want to be able to query against the entire data set but this mean I must know the names of all the models (which means selecting from MDSYS>RDF_MODEL$). Here is the code I came up with. This gives me a Dataset that I can then pass to QueryExecutionFactory.create(Query, Dataset). Any suggestions?

            private static final String SELECT_MODELS =
            "SELECT model_name FROM MDSYS.RDF_MODEL$ WHERE owner=? and model_name != ?";
            private static final String MODEL_NAME = "model_name";
                 
            /**
            * The name of a reserved model representing all semantic data in the database.
            */
            private static final String DATASET_MODEL_NAME = "DATASET";
                 
            public Dataset getDataSet() {
            Dataset ds = null;
            Oracle oracle = getOracle();

            // The hard way: manually
            try {
            // Get all accessible models in the store
            PreparedStatement stmt = oracle.getConnection().prepareStatement(SELECT_MODELS);
            stmt.setString(1, oracle.getConnection().getUserName());
            stmt.setString(2, DATASET_MODEL_NAME);
            ResultSet rs = stmt.executeQuery();
                 
            // Add them to a composite model                    
            List<String> modelNames = new ArrayList<String>();
            while ( rs.next() ) {
            modelNames.add(rs.getString(MODEL_NAME));          
            }
            stmt.close();

            // create a dataset from the composite model
            Attachment attachment = Attachment.createInstance(
            (String[])modelNames.toArray(new String[0]),
            new String[0],
            InferenceMaintenanceMode.NO_UPDATE,
            QueryOptions.QUERY_VALID_ONLY );

            GraphOracleSem graph = new GraphOracleSem( oracle,
            DATASET_MODEL_NAME, attachment );
            ds = DatasetFactory.create(new ModelCom(graph));
            } catch (SQLException e) {
            log.warn("SQL Exception caught", e);               
            } catch (Exception e) {
            log.warn("Exception thrown.", e);
            }
            return ds;
            }

            Thanks!
            • 3. Re: Running a SPARQL query across all models
              alwu-Oracle
              That should work.

              QueryExecutionFactory can take ModelOracleSem as the second parameter as well.

              In the newer version of Oracle Jena Adaptor, a new QueryOptions constant is introduced to allow query multiple models without removing duplicate first. And removing duplicates can be very costly if size of data is significant.
              • 4. Re: Running a SPARQL query across all models
                652134
                I was looking at the Examples.java file that comes with the Jena Adapter. I want to execute SPARQL queries against multiple models. I pulled some code from the testAttachedTwoRBs method:

                Attachment attachment = Attachment.createInstance(
                Attachment.NO_ADDITIONAL_MODELS, rbs,
                InferenceMaintenanceMode.UPDATE_WHEN_COMMIT,
                QueryOptions.DEFAULT);

                GraphOracleSem graph3 = new GraphOracleSem(
                oracle, modelName, attachment);
                ModelOracleSem model3 = new ModelOracleSem(graph3);
                populateGraph(model3.getGraph());

                I think I follow the code. I do have a question about the modelName parameter in the 'new GraphOracleSem()' statement. What should I use for the modelName? Is it the default model name?

                On a side question, what is the best strategy for designating a default model when selecting from multiple models? Do you select the model you expect to have the most data? Do you select the model you expect to match the fewest matches? Also, I really don't care about the Rule Base when I am creating my Attachment instance. What do I enter for the rulebaseName parameter?
                • 5. Re: Running a SPARQL query across all models
                  alwu-Oracle
                  Here is a simple example. To attach "model2" to the primary graph "modelName"
                  one can do something as follows.

                  Attachment attachment = Attachment.createInstance(model2);
                  GraphOracleSem graph = new GraphOracleSem(
                  oracle, modelName, attachment);
                  ModelOracleSem model = new ModelOracleSem(graph);

                  As to which one to use as the "primary" or "default," you should choose the
                  one that you want to perform add/delete against. If there is no need
                  to add triple or remove triple for any of the models, then anyone is fine.