Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disambiguating resources with same predicate in JSON-LD

Tags:

ruby

rdf

json-ld

I'm having trouble figuring out how to disambiguate resources that use the same predicate in advance. I'm an RDF novice, so please excuse my terminology: I'll try to explain what I mean with examples.

I have an Interview resource/model with a (simplified) context like this:

{
  "id": {
    "@id": "http://purl.org/dc/terms/identifier"
  },
  "interviewers": {
    "@id": "http://purl.org/dc/terms/contributor",
    "@type": "@id",
    "@container": "@set"
  },
  "title": {
    "@id": "http://purl.org/dc/terms/title"
  },
  "interviewees": {
    "@id": "http://purl.org/dc/terms/contributor",
    "@type": "@id",
    "@container": "@set"
  }
}

My Interviewer and Interviewee resources have contexts like this:

{
  "id": {
    "@id": "http://purl.org/dc/terms/identifier"
  },
  "name": {
    "@id": "info:repository/ive/name"
  }
}

I then create a resource that looks like this:

{
  "id": "06bad25f-83c1-4ee5-b055-0cb87d4c06be",
  "interviewers": [
    {
      "id": "b0c262ce-7eb3-47f2-b212-a0e71cca0c92",
      "name": "Somebody",
      "@context": {
        ...
      },
      "@id": "urn:uuid:b0c262ce-7eb3-47f2-b212-a0e71cca0c92",
      "@type": [
        "http://id.loc.gov/vocabulary/relators/ivr"
      ]
    }
  ],
  "title": "Interview with So and So",
  "interviewees": [
    {
      "id": "bd6bb9ec-f417-4f81-af69-e3d191e3f73b",
      "name": "A third person",
      "gender": "male",
      "@context": {
        ...
      },
      "@id": "urn:uuid:bd6bb9ec-f417-4f81-af69-e3d191e3f73b",
      "@type": [
        "http://id.loc.gov/vocabulary/relators/ive"
      ]
    }
  ],
  "@context": {
    ...
  },
  "@id": "urn:uuid:06bad25f-83c1-4ee5-b055-0cb87d4c06be",
  "@type": [
    "info:repository/interview"
  ]
}

Everything is good, and I can store this "object" to my repository (I'm using RDF.rb libraries). However, problems arise when I then try to extract the object and "re-serialize" it. For example (excuse the Ruby code),

query = repository.query(:subject => RDF::URI(uri))
JSON.parse(query.dump(:jsonld, :context => Interview.context))

These lines extract relevant statements from the repository, and then mash them into a JSON-LD "resource" with the appropriate context. However, both interviewees and interviewers are moved into the interviewees attribute.

Of course, this makes perfect sense, since both interviewers and interviewees are related to the interview resource with the dc:contributor predicate (they are only distinguished by their individual types).

I need to make the dump process aware of the related resource types, but I don't know of any way to add that information to the interview's context.

I don't know if this is even possible according to the current JSON-LS specs. This issue seems like it might be relevant, but I don't really know enough about RDF/JSON-LD to know for sure.

I could use different predicates for interviewers and interviewees, but it doesn't seem like I should have to do so. Any suggestions?

Note: I've also asked this question at answers.semanticweb.com.

ADDITIONAL INFORMATION

I've modeled my contributor relations in this way (where an interviewer is a contributor with a type http://id.loc.gov/vocabulary/relators/ivr) based on one of the the recommended ways for qualifying DC properties. For example, one can express a MESH subject on a resource like:

<rdf:Description>
  <dc:subject>
    <dcterms:MESH>
      <rdf:value>D08.586.682.075.400</rdf:value>
      <rdfs:label>Formate Dehydrogenase</rdfs:label>
    </dcterms:MESH>
  </dc:subject>
</rdf:Description>

Suppose I had:

<rdf:Description>
  <dc:subject>
    <dcterms:MESH>
      <rdf:value>D08.586.682.075.400</rdf:value>
      <rdfs:label>Formate Dehydrogenase</rdfs:label>
    </dcterms:MESH>
  </dc:subject>
  <dc:subject>
    <dcterms:LCSH>
      <rdf:value>Formate Dehydrogenase</rdf:value>
    </dcterms:LCSH>
  </dc:subject>
</rdf:Description>

I would like to be able to reference a lcsh_subjects "property", where lcsh_subjects represents those nodes that are related to the resource with dc:subject AND that have type dcterms:LCSH. However, I realize that I'm probably thinking about JSON-LD model the wrong way.

like image 533
Jacob Brown Avatar asked Jan 17 '14 19:01

Jacob Brown


People also ask

What is @context in JSON-LD?

JSON-LD introduces the concept of the @context element which provides additional information allowing the computer to interpret the rest of the data with more clarity and depth. Furthermore the JSON-LD specification enables you to define a unique @type associating a well-defined data model to the data itself.

What is @ID in JSON-LD?

JSON-LD supports references to objects with a reserved key @id which can be used either as an object identifier or a reference to an object identifier. The value of @id must be a string.

Is JSON an RDF LD?

In JSON-LD lists are part of the data model whereas in RDF they are part of a vocabulary, namely [RDF11-SCHEMA]. RDF values are either typed literals (typed values) or language-tagged strings whereas JSON-LD also supports JSON's native data types, i.e., number, strings, and the boolean values true and false.


1 Answers

You may be confused about the @id to use for both interviewers and interviewees. You've defined them both with the same @id, meaning that they are the same predicate. They are defined to be contributors to the resource, but there's nothing to make them distinct from each other. You may consider that what you mean by "interviewers" is a predicate that is a sub-property of dc:contributor, and the same for "interviewees". It might be better to choose an existing vocabulary that already has the notion of interviewers and interviewees. Alternatively, create your own vocabulary which defines the terms you need, and use this for creating context types.

You're also escaping the URIs used within your object (e.g., "http://purl.org/dc/terms/identifier"), which might not yield what you want, just use regular URIs such as "http://purl.org/dc/terms/identifier".

(Also, you use an "info" prefix, which is undefined. And, it's not necessary to declare @context at every level).

For example, you might consider creating http://example.foo/my-vocab# and defining properties within that (using your own dereferencable IRI, of course):

{
  "@context": {
    "dc": "dc:identifier",
    "rdf": "URI:http:/www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#"
  },
  "@graph": [
    {
      "@id": "http://example.foo/interviewees",
      "@type": "rdf:Property",
      "rdfs:comment": "Interviewee",
      "rdfs:subPropertyOf": {
        "@id": "dc:contributor"
      }
    },
    {
      "@id": "http://example.foo/interviewers",
      "@type": "rdf:Property",
      "rdfs:comment": "Interviewer",
      "rdfs:subPropertyOf": {
        "@id": "dc:contributor"
      }
    }
  ]
}

You could then use this with the context of your object as follows:

{
  "@context": {
    "id": "http://purl.org/dc/terms/identifier",
    "myvocab": "http://example.foo/myvocab#",
    "info": "http://example.foo/info#",
    "interviewers": {
      "@id": "myvocab:interviewers",
      "@type": "@id",
      "@container": "@set"
    },
    "title": "http://purl.org/dc/terms/title",
    "interviewees": {
      "@id": "myvocab:interviewees",
      "@type": "@id",
      "@container": "@set"
    }
  },
  "id": "06bad25f-83c1-4ee5-b055-0cb87d4c06be",
  "interviewers": [
    {
      "id": "b0c262ce-7eb3-47f2-b212-a0e71cca0c92",
      "name": "Somebody",
      "@id": "urn:uuid:b0c262ce-7eb3-47f2-b212-a0e71cca0c92",
      "@type": [
        "http://id.loc.gov/vocabulary/relators/ivr"
      ]
    }
  ],
  "title": "Interview with So and So",
  "interviewees": [
    {
      "id": "bd6bb9ec-f417-4f81-af69-e3d191e3f73b",
      "name": "A third person",
      "gender": "male",
      "@id": "urn:uuid:bd6bb9ec-f417-4f81-af69-e3d191e3f73b",
      "@type": [
        "http://id.loc.gov/vocabulary/relators/ive"
      ]
    }
  ],
  "@id": "urn:uuid:06bad25f-83c1-4ee5-b055-0cb87d4c06be",
  "@type": [
    "info:repository/interview"
  ]
}

(Also, check this out on the JSON-LD playground

If you turn this into something like Turtle (try http://rdf.greggkellogg.net/), you'd get the following:

@prefix dc: <http://purl.org/dc/terms/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<urn:uuid:06bad25f-83c1-4ee5-b055-0cb87d4c06be> a <http://example.foo/info#repository/interview>;
   dc:title "Interview with So and So";
   <http://example.foo/myvocab#interviewees> <urn:uuid:bd6bb9ec-f417-4f81-af69-e3d191e3f73b>;
   <http://example.foo/myvocab#interviewers> <urn:uuid:b0c262ce-7eb3-47f2-b212-a0e71cca0c92>;
   dc:identifier "06bad25f-83c1-4ee5-b055-0cb87d4c06be" .

<urn:uuid:b0c262ce-7eb3-47f2-b212-a0e71cca0c92> a <http://id.loc.gov/vocabulary/relators/ivr>;
   dc:identifier "b0c262ce-7eb3-47f2-b212-a0e71cca0c92" .

<urn:uuid:bd6bb9ec-f417-4f81-af69-e3d191e3f73b> a <http://id.loc.gov/vocabulary/relators/ive>;
   dc:identifier "bd6bb9ec-f417-4f81-af69-e3d191e3f73b" .
like image 100
Gregg Kellogg Avatar answered Sep 19 '22 23:09

Gregg Kellogg