5 Replies Latest reply on Feb 8, 2007 10:08 PM by Mannamal-Oracle

    Problem With defining Blank nodes

    538641
      Hey,

      I'm reasonably new at RDF and Oracle. And I'm testing for my application Things to insert a blank node to represent an n-ary relationship.
      After some experimenting i found out that, when i added a "_:NodeId" as subject or object in my triple, oracle creates a generic name for my 'blank' node with node value: _:ORABN2451A71D04BD5F79E040780A01002DC3.
      The problem began when i tried different _:NodeId as subject and object for triplets, to my surprise, the node value stayed the same.
      But never where any rows were added in the tabel RDF_BLANK_NODE$.

      All this was tested with the insert query:
      Insert Into thi_rdf_data(rdf_triple)
      VALUES(sdo_rdf_triple_s('things_rdf',
                               '_:NodeId',
                               'http://www.w3.org/200/01/rdf-schema#label',
                               'test'
                               )
           );



      Only after i altered the query to:
      Insert Into thi_rdf_data(rdf_triple)
      VALUES(sdo_rdf_triple_s('things_rdf',
                               '_:NodeId',
                               'http://www.w3.org/200/01/rdf-schema#label',
                               'test',
                               201
                               )
           );


      New entries were added to the RDF_BLANK_NODE$ table, but still all with the same node_value.

      Anyone have an idea what I'm doing wrong here?

      Thank in advance

      Jeroen van Lier
        • 1. Re: Problem With defining Blank nodes
          Mannamal-Oracle
          Hi,

          First, let me briefly explain how Oracle handles blank nodes in 10gR2.

          Internally we generate an Oracle specific identifier for each blank node - this is done mainly to ensure that blank nodes from different models do not clash with each other. For example the string '_:jA1' might be generated by a tool to represent blank nodes, and might mean entirely different things in different models. To distinguish them from each other, we internally generate a different string with a _:ORA prefix.

          If an application wants to store the fact that two blank nodes are identical, then the data has to be loaded using the 'blank node reuse' parameter (described in section 1.4.2 of the documentation). Within a model this will ensure that two blank nodes represented by the same string (say '_:NodeId') have the same internal string. This would ensure that they match in a query. When this parameter is used, the rdf_blank_node$ table is populated (as you observed).

          This has resulted in some confusion and in an upcoming release we have made some changes to make them less confusing.

          In 10gR2, the common usage is likely to be that identical blank node strings within a model mean the same thing. Thus we would recommend loading data using the 'blank node reuse' parameter so that the blank nodes within a model represented by the same string will have the same internal representation.

          You mention that the same internal string is generated for multiple blank nodes. That will not be the case - I think it is likely that the strings appear the same but are not really the same - if you look closely you might find atleast one character different.

          Melli
          • 2. Re: Problem With defining Blank nodes
            24743
            Hi Melli

            Could you give an example showing how to create f.ex a bag collection and how to query it?

            Thanks - Christian
            • 3. Re: Problem With defining Blank nodes
              Mannamal-Oracle
              Hi Christian,

              As described in the RDF Primer, a resource can be described to be of type rdf:Bag, with container membership properties of the form rdf:_n for each member of the Bag container. Such a container resource, which is defined to be of type rdf:Bag, is often represented as a blank node. If you are using blank nodes, read the above post carefully, and use the 'blank node reuse' parameter while loading data - whether you load using INSERT statements or using the batch load tool.

              Extending the family example described in the documentation, we can model the fact that Tom's cousins are Jack and Cathy using rdf:Bag. Examples of INSERT statements could be as follows (note that the constructor used is the one which allows for the specification of the model_id parameter in the end, which indicates that blank nodes have to be reused within that model; you can find the model_id for a given model by querying the mdsys.rdf_model$ table):

              -- declaring a container resource, and representing it using a blank node

              insert into family_rdf_data values (100, sdo_rdf_triple_s('family', '_:CousinsNode', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag>', <model_id>));

              -- defines that Tom has a :cousin property, and links the container resource we
              -- defined above to Tom

              insert into family_rdf_data values(101, sdo_rdf_triple_s('family', '<http://www.example.org/family/Tom>', '<http://www.example.org/family/Cousin>', '_:CousinsNode', <model_id>));

              -- adding a member of the container resource

              insert into family_rdf_data values(102, sdo_rdf_triple_s('family', '_:CousinsNode', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#_2>' , '<http://www.example.org/family/Cathy>', <model_id>));

              -- adding a member of the container resource

              insert into family_rdf_data values(103, sdo_rdf_triple_s('family', '_:CousinsNode', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#_1>' , '<http://www.example.org/family/Jack>', <model_id>));

              -- now we can query; variable ?a represents the container resource, in this
              -- case a blank node

              select c, b
              from table(
              sdo_rdf_match(
              '(?c :Cousin ?a)(?a ?p ?b)',
              sdo_rdf_models('family'), null,
              SDO_RDF_Aliases(SDO_RDF_Alias('','http://www.example.org/family/')), null));

              Melli
              • 4. Re: Problem With defining Blank nodes
                24743
                Hi Melli

                Thank you for the example - just what I needed.

                The result of your query is

                C B
                ------------------------------------------ -----------------------------------------------------------
                http://www.example.org/family/Tom     http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag
                http://www.example.org/family/Tom     http://www.example.org/family/Jack
                http://www.example.org/family/Tom     http://www.example.org/family/Cathy

                so the first record has to be filtered out.

                A few comments:

                1) It's a bit strange that one has to give the <model_id> as parameter when the first parameter is the <model_name> - a boolean like <reuse> would be more intuitive.

                2) There does not seem to be a check on the word "Bag" (anything goes).

                3) '(?c :Cousin ?b)' would be more intuitive than '(?c :Cousin ?a)(?a ?p ?b)' - but maybe that's against the SPARQL syntax.

                Christian
                • 5. Re: Problem With defining Blank nodes
                  Mannamal-Oracle
                  ----
                  http://www.example.org/family/Tom     http://www.w3.org/19
                  99/02/22-rdf-syntax-ns#Bag
                  http://www.example.org/family/Tom     http://www.example.o
                  rg/family/Jack
                  http://www.example.org/family/Tom     http://www.example.o
                  rg/family/Cathy

                  so the first record has to be filtered out.
                  Yes.

                  >
                  A few comments:

                  1) It's a bit strange that one has to give the
                  <model_id> as parameter when the first parameter is
                  the <model_name> - a boolean like <reuse> would be
                  more intuitive.
                  That is an interesting comment! Indeed, the interface could be changed as you suggest, and we might do that in a future release. The current interface was designed from the point of view of maximum flexibility, where the user could to choose to re-use blank nodes from a different model, if both models are related. This could change in the future, and we now strongly recommend re-using blank nodes only within a model, and to always re-use blank nodes within a model.

                  >
                  2) There does not seem to be a check on the word
                  "Bag" (anything goes).
                  Yes, we do not do any checks in the current release, we just treat the data as data the application wants to use. The above example follows the recommended guidelines of modeling using a "Bag", and using "Bag" (instead of any other string) will help other tools use the data.

                  >
                  3) '(?c :Cousin ?b)' would be more intuitive than
                  '(?c :Cousin ?a)(?a ?p ?b)' - but maybe that's
                  against the SPARQL syntax.
                  For ('?c :Cousin ?b) to match a sub-graph in the RDF graph, the direct link with predicate :Cousin will have to exist between ?c and ?b. But since the :Bag type is used, and the modeling of the :Bag type uses a blank node or some other resource in between the two nodes, the query in SPARQL will have to be constructed so that such a subgraph is matched (in other words, the query has to be constructed with two patterns as shown in the example above).

                  Thanks for your feedback!

                  Melli