4 Replies Latest reply on Jan 18, 2012 4:56 PM by alwu-Oracle

    Deleting Triples from a Model

    900576
      I have been trying to find the most efficient and cleanest way to delete a Triple, or list of Triples from the Oracle Database Model using the new Jena Adapter for 11.2.0.3.

      I have a few situations where I know a Subject URI and a Predicate URI and I was to delete all of the Triples reguardless of the Object values, and I also have a case where I know the Object URI and the Predicate URI and I want to delete the Triples that match it reguardless of the Subject URI.

      I was first attempting to use the API GraphOracleSem.delete(Triple), however when I used Node.ANY as the Object or Subject I didn't know the values to, it would not work, and I recieved an error "ERROR [main] (SimpleLog.java:237) - encode: unknown type". I was also unable to use variable in the SPARQL UPDATE syntax 'DELETE DATA {?s <predicate#uri> "literal" }'

      I have found another way by using the Resource.removeProperties and Resource.removeAll(Property) methods. However, I still cannot find a way to delete Triples when I only know the Predicate and Object.


      Thanks
      -MichaelB
        • 1. Re: Deleting Triples from a Model
          alwu-Oracle
          Hi MichaelB,

          You are not supposed to use wild card with graph.delete(Triple t) API. Jena's in memory graph does not support it. Oracle's graph does not support it either.

          One way to remove a subset of triples is to find them and remove them iteratively.

          Here is an example.

          Oracle oracle = new Oracle(jdbcUrl, user, password);
          Model model = ModelOracleSem.createInstance(oracle, modelName);

          Node nodeSubject = Node.createURI("http://my.com/s1");
          Node nodePredicate = Node.createURI("http://my.com/hasAlias");

          model.getGraph().add(Triple.create(nodeSubject, nodePredicate,
          Node.createLiteral("John")));
          model.getGraph().add(Triple.create(nodeSubject, nodePredicate,
          Node.createLiteral("Johnny")));

          model.getGraph().add(Triple.create(nodeSubject,
          Node.createURI("http://my.com/hasFriend"),
          Node.createLiteral("Mary")));

          {

          // try out in-memory Jena model
          Model modelInMem = ModelFactory.createDefaultModel();
          modelInMem.add(model);
          psOut.println("size of the in memory model " + model.getGraph().size());
          modelInMem.getGraph().delete(Triple.create(nodeSubject, nodePredicate, Node.ANY));
          psOut.println("size of the in memory model after deletion " + model.getGraph().size());

          modelInMem.close();
          }


          psOut.println("size of the Oracle model " + model.getGraph().size());
          ExtendedIterator<Triple> results = model.getGraph().find(nodeSubject, nodePredicate, null);
          while (results.hasNext()) {
          Triple t = results.next();
          model.getGraph().delete(t);
          }
          psOut.println("size of the Oracle model after delete " + model.getGraph().size());

          // After deletion
          results = GraphUtil.findAll(model.getGraph());
          while (results.hasNext()) {
          psOut.println("triples after deletion: " + results.next());
          }

          model.close();
          oracle.dispose();


          Output of the above code:

          size of the in memory model 3
          size of the in memory model after deletion 3
          size of the Oracle model 3
          size of the Oracle model after delete 1
          triples after deletion: http://my.com/s1 @http://my.com/hasFriend "Mary"


          Hope it helps,

          Zhe
          • 2. Re: Deleting Triples from a Model
            alwu-Oracle
            Hi,

            Sorry I missed the SPARQL Update question in your original post. Here is how one can use SPARQL Update.
            Please check Section 7.8 of http://docs.oracle.com/cd/E11882_01/appdev.112/e11828/sem_jena.htm for
            details.

            Continue from my previous code snippet.

            ...
            ...
            psOut.println("size of the Oracle model " + model.getGraph().size());
            ((GraphOracleSem) (model.getGraph())).commitTransaction();
            ExtendedIterator<Triple> results = model.getGraph().find(nodeSubject, nodePredicate, null);
            while (results.hasNext()) {
            Triple t = results.next();
            model.getGraph().delete(t);
            }
            psOut.println("size of the Oracle model after delete " + model.getGraph().size());

            // After deletion
            results = GraphUtil.findAll(model.getGraph());
            while (results.hasNext()) {
            psOut.println("triples after deletion: " + results.next());
            }

            // Undo the deletes so that we can try another approach.
            //
            ((GraphOracleSem) (model.getGraph())).rollbackTransaction();
            psOut.println("size of the Oracle model " + model.getGraph().size());

            // Now use SPARQL Update
            UpdateAction.parseExecute(
            "DELETE { <http://my.com/s1> <http://my.com/hasAlias> ?o } " +
            " WHERE { <http://my.com/s1> <http://my.com/hasAlias> ?o } ",
            model);
            psOut.println("size of the Oracle model after SPARQL UPDATE " + model.getGraph().size());

            model.close();
            oracle.dispose();


            ==> Output is

            size of the in memory model 3
            size of the in memory model after deletion 3
            size of the Oracle model 3
            size of the Oracle model after delete 1
            triples after deletion: http://my.com/s1 @http://my.com/hasFriend "Mary"
            size of the Oracle model 3
            size of the Oracle model after SPARQL UPDATE 1

            Thanks,

            Zhe Wu
            • 3. Re: Deleting Triples from a Model
              900576
              I am going to use

              graph.getBulkUpdateHandler().delete(graph.find(null, null, o));

              and

              graph.getBulkUpdateHandler().delete(graph.find(null, p, o));

              to detele the triples that match the s, p, o combination.


              Is this better than iterating over the ExtendedIterator and calling graph.delete(Triple)?

              Thanks.
              • 4. Re: Deleting Triples from a Model
                alwu-Oracle
                Hi,

                These two approaches are very, very similar. The only difference is OracleBulkUpdateHandler's logic will perform a little bit of buffering. I don't think the difference has a significant impact on performance.

                Thanks,

                Zhe Wu