2

I was wondering how I could model the following with r2rml:

Person -> has an address --> Blank Node [ Street Name, Postal Code, City ]

I'm note sure how I can add street name, postal code and city to the blank node within the rr:objectMap

(Additional question: Is a rr:class mandatory for a rr:BlankNode?)

Any suggestions? :)

<#Person>
    rr:logicalTable [ rr:tableName "PERSON" ];
    rr:subjectMap [
      rr:template "http://ex.com/data/PersonClass/{ID}";
      rr:class ex:PersonClass;
    ];
    rr:preciateObjectMap [
      rr:predicate ex:hasAddress;
      rr:objectMap [
        rr:termType rr:BlankNode;
        ## How/where can a add the street name, postal code, city? ##
      ];
    ].
Kody
  • 1,154
  • 3
  • 14
  • 31

1 Answers1

2

Should be not too difficult. First you take the R2RML mapping you have created and create a blank node for the address. Give it a unique name by using a template, but do not give it an IRI so it is interpreted as a blank node.

<#Person>
    rr:logicalTable [ rr:tableName "PERSON" ];
    rr:subjectMap [
      rr:template "http://ex.com/data/PersonClass/{ID}";
      rr:class ex:PersonClass;
    ];
    rr:preciateObjectMap [
      rr:predicate ex:hasAddress;
      rr:objectMap [
        rr:template "BlankAddressNode{ADDRESSID}"; 
        rr:termType rr:BlankNode;
      ];
    ].

Note: ADDRESSID in table PERSON is considered a foreign to the primary key of ADDRESS table.

Next you create the blank node with rdf:type and everything else.

<#Address>
    rr:logicalTable [ rr:tableName "ADDRESS" ];
    rr:subjectMap [
      rr:template "BlankAddressNode{ID}"; 
      rr:termType rr:BlankNode;
      rr:class ex:AddressClass;
    ];
    rr:predicateObjectMap [
        rr:predicate    ex:street;
        rr:objectMap    [  rr:column "Street"]
    ];
    .

Note: ID is primary key of ADDRESS table.

You can do this with a join too... but I think from a tutorial point of view this is clearer.

Natan Cox
  • 1,495
  • 2
  • 15
  • 28
  • First of all... thanks :) But, I don't understand the part with `rr:template "BlankAddressNode{ID}";` Is that a custom variable you're using? Is it working inside a `rr:subjectMap`? – Kody Mar 21 '16 at 08:52
  • First of: you need both mappings in the same file. During processing of that one R2RML mapping file it will use identifiers for each blank node. For example if you are processing Person row with ID 1025 it will create a 'BlankAddressNode1025' blank node. It will use that blank node in hasAddress and Address mappings. Note: It might not be the 'correct' way since turtle specification says blank nodes need to be formatted like _:BlankAddressNode1025 but it worked for me. – Natan Cox Mar 21 '16 at 09:17
  • I'll try this :) Do you know what the 'correct' way would look like? – Kody Mar 21 '16 at 09:21
  • From my experience you are required to add a rr:class in rr:subjectMap even for blank nodes (but it might depend on the tool). In theory you can but a very generic class here like owl:Thing (but again, it might depend on the tool). – Natan Cox Mar 21 '16 at 09:22
  • Just try `rr:template "_:BlankAddressNode{ID}"`. Also note: this is not guaranteed to be the final value of you blank node in de RDF store. – Natan Cox Mar 21 '16 at 09:24
  • Is the address data in your example supposed to be in a different table? Could I combine such a scenario, having the blank node data from another table? :) – Kody Mar 21 '16 at 15:51
  • Not sure what you mean by "table". RDF works with "resources" and you want to create a Person and Address resource (from one SQL table for example). Those are 2 different ''types'' of resources and each type of resource needs a separate R2RML mapping. Hence you need 2 mappings. I could imagine some extension in R2RML do handle both types in one mapping but that is not possible in R2RML and I do not think it is logical either. Separate mappings for separate types is cleaner. – Natan Cox Mar 21 '16 at 15:58
  • What I meant is... Having data of a person in a relational table called `Person` and having the address data in a table called `Address`. – Kody Mar 21 '16 at 16:09
  • Yes you can. I slightly modified the example in the answer accordingly. – Natan Cox Mar 21 '16 at 16:12
  • I tried it with db2triples. It tells me it doesn't know the `adressid` column inside <#Person> – Kody Mar 21 '16 at 16:25
  • Those where just example column names because I do not have access to your database schema. Check your schema and fill in the correct names. – Natan Cox Mar 21 '16 at 16:28
  • I know that you gave me examples :) I already filled the correct IDs. `<#Person>`has `rr:template "_:BlankAddressNode{ADDRESS_ID}";` inside the objectMap, and `<#Address>` has `rr:template "_:BlankAddressNode{PERSON_ID}` inside the objectMap. – Kody Mar 21 '16 at 16:35
  • I had to swap the IDs and rdf was generated. But the data form the address blank node doesn't correspond to the person tuples. Can I combine that with a join somehow? – Kody Mar 22 '16 at 07:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/106983/discussion-between-natan-cox-and-kody). – Natan Cox Mar 22 '16 at 07:46