Experts and Institutions#

About#

This thematic type provides a way to describe the experts and institutions. In this case the following definitions are used:

Expert: A person who has a deep understanding of a particular subject area.

Institution: A group of people working together to provide a particular service.

Example: Person Graph#

The following graph present a basic record we might use for a person.
We will break down some of the key properties used in this graph.

As Ocean InfoHub is levergaing Schema.org we are using schema.org/Person for this type. Any of the properties of Person seen there are valid to use in such a record.

While publishers are free to use as many elements as they wish, our goal with this documentation is provide a simple example that address some of the search and discovery goals of OIH along with those properties most useful in the linking of resources between OIH participants.

 1{
 2  "@context": {
 3    "@vocab": "https://schema.org/"
 4  },
 5  "@id": "https://example.org/id/x",
 6  "@type": "Person",
 7  "name": "Jane Doe",
 8  "jobTitle": "Professor",
 9  "telephone": "(425) 123-4567",
10  "url": "http://www.janedoe.com",
11  "knowsAbout": [
12    {
13      "@type": "Text",
14      "description": "Invasive species in brackish water"
15    },
16    {
17      "@type": "URL",
18      "url": "https://www.wikidata.org/wiki/Q183368"
19    },
20    {
21      "@id": "https://example.org/id/course/x",
22      "@type": "Course",
23      "description": "In this course ...",
24      "url": "URL to the course"
25    }
26  ],
27  "identifier": {
28    "@id": "https://orcid.org/0000-0002-2257-9127",
29    "@type": "PropertyValue",
30    "propertyID": "https://registry.identifiers.org/registry/orcid",
31    "url": "https://orcid.org/0000-0002-2257-9127",
32    "description": "Optional description of this record..."
33  },
34  "nationality": [
35    {
36      "@type": "Country",
37      "name": "Fiji"
38    },
39    {
40      "@type": "DefinedTerm",
41      "url": "https://unece.org/trade/cefact/unlocode-code-list-country-and-territory",
42      "inDefinedTermSet": "UN/LOCODE Code List by Country and Territory",
43      "name": "Fiji",
44      "termCode": "FJ"
45    }
46  ],
47  "knowsLanguage" :{
48    "@type": "Language",
49    "name": "Spanish",
50    "alternateName": "es"
51  }
52}
import json
from pyld import jsonld
import os, sys

currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils

with open("./graphs/person.json") as dgraph:
    doc = json.load(dgraph)

context = {
    "@vocab": "https://schema.org/",
}

compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
../../_images/README_1_01.svg

Details: Indentifier#

For each profile there are a few key elements we need to know about. One key element is what the authoritative reference or canonical identifier is for a resource.

import json
from rdflib.extras.external_graph_libs import rdflib_to_networkx_multidigraph
from rdflib.extras.external_graph_libs import rdflib_to_networkx_graph
from pyld import jsonld
import graphviz
import os, sys

currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils

with open("./graphs/person.json") as dgraph:
    doc = json.load(dgraph)

frame = {
  "@context": {"@vocab": "https://schema.org/"},
  "@explicit": "true",
  "@type":     "Person",
  "identifier": ""
}

context = {
    "@vocab": "https://schema.org/",
}

compacted = jsonld.compact(doc, context)

framed = jsonld.frame(compacted, frame)
jd = json.dumps(framed, indent=4)
print(jd)

jbutils.show_graph(framed)
{
    "@context": {
        "@vocab": "https://schema.org/"
    },
    "@id": "https://example.org/id/x",
    "@type": "Person",
    "identifier": {
        "@id": "https://orcid.org/0000-0002-2257-9127",
        "@type": "PropertyValue",
        "description": "Optional description of this record...",
        "propertyID": "https://registry.identifiers.org/registry/orcid",
        "url": "https://orcid.org/0000-0002-2257-9127"
    }
}
../../_images/README_3_11.svg

Details: nationality#

Nationality provide connections to languages a person is connected with. The property, schema.org/nationality, is used to present that. In the OIH we need to state what the semantics of nationality are for our use case.

import json
from rdflib.extras.external_graph_libs import rdflib_to_networkx_multidigraph
from rdflib.extras.external_graph_libs import rdflib_to_networkx_graph
from pyld import jsonld
import graphviz
import os, sys

currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils

with open("./graphs/person.json") as dgraph:
    doc = json.load(dgraph)

frame = {
  "@context": {"@vocab": "https://schema.org/"},
  "@explicit": "true",
  "@type":     "Person",
  "nationality": ""
}

context = {
    "@vocab": "https://schema.org/",
}

compacted = jsonld.compact(doc, context)

framed = jsonld.frame(compacted, frame)
jd = json.dumps(framed, indent=4)
print(jd)

jbutils.show_graph(framed)
{
    "@context": {
        "@vocab": "https://schema.org/"
    },
    "@id": "https://example.org/id/x",
    "@type": "Person",
    "nationality": [
        {
            "@type": "Country",
            "name": "Fiji"
        },
        {
            "@type": "DefinedTerm",
            "inDefinedTermSet": "UN/LOCODE Code List by Country and Territory",
            "name": "Fiji",
            "termCode": "FJ",
            "url": "https://unece.org/trade/cefact/unlocode-code-list-country-and-territory"
        }
    ]
}
../../_images/README_5_11.svg

Note

The visual above demonstrates an issue that can be seen in several of the graph. Where we don’t use an @id the graph will be represented as a “blank node”.
These will be uniquely identified in the graph, however, in the construction of the visual this is a common blank node and results in the double arrows pointing to an underscore. This is a visualization issue and not a proper representation of the graph structure.

Details: knowsLanguage#

Knows about provide connections to languages a person is connected with. The property, schema.org/knowsLanguage, is used to present that. Multiple languages can be expressed using the JSON array [] syntax.

import json
from rdflib.extras.external_graph_libs import rdflib_to_networkx_multidigraph
from rdflib.extras.external_graph_libs import rdflib_to_networkx_graph
from pyld import jsonld
import graphviz
import os, sys

currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils

with open("./graphs/person.json") as dgraph:
    doc = json.load(dgraph)

frame = {
  "@context": {"@vocab": "https://schema.org/"},
  "@explicit": "true",
  "@type":     "Person",
  "knowsLanguage": ""
}

context = {
    "@vocab": "https://schema.org/",
}

compacted = jsonld.compact(doc, context)

framed = jsonld.frame(compacted, frame)
jd = json.dumps(framed, indent=4)
print(jd)

jbutils.show_graph(framed)
{
    "@context": {
        "@vocab": "https://schema.org/"
    },
    "@id": "https://example.org/id/x",
    "@type": "Person",
    "knowsLanguage": {
        "@type": "Language",
        "alternateName": "es",
        "name": "Spanish"
    }
}
../../_images/README_7_11.svg

Details: Knows About#

Knows about provide connections to resources a person is connected with. The property, schema.org/knowsAbout, can connect a Person or Organization to Text, URL or any Thing type.

import json
from rdflib.extras.external_graph_libs import rdflib_to_networkx_multidigraph
from rdflib.extras.external_graph_libs import rdflib_to_networkx_graph
from pyld import jsonld
import graphviz
import os, sys

currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils

with open("./graphs/person.json") as dgraph:
    doc = json.load(dgraph)

frame = {
  "@context": {"@vocab": "https://schema.org/"},
  "@explicit": "true",
  "@type":     "Person",
  "knowsAbout": ""
}

context = {
    "@vocab": "https://schema.org/",
}

compacted = jsonld.compact(doc, context)

framed = jsonld.frame(compacted, frame)
jd = json.dumps(framed, indent=4)
print(jd)

jbutils.show_graph(framed)
{
    "@context": {
        "@vocab": "https://schema.org/"
    },
    "@id": "https://example.org/id/x",
    "@type": "Person",
    "knowsAbout": [
        {
            "@type": "Text",
            "description": "Invasive species in brackish water"
        },
        {
            "@type": "URL",
            "url": "https://www.wikidata.org/wiki/Q183368"
        },
        {
            "@id": "https://example.org/id/course/x",
            "@type": "Course",
            "description": "In this course ...",
            "url": "URL to the course"
        }
    ]
}
../../_images/README_9_11.svg

Example: Institution Graph#

Here we have an example of an data graph for type schema.org/Organization.
For the identifier we are using the a GRID, but this could also be something like a ROR.

 1{
 2    "@context": {
 3        "@vocab": "https://schema.org/"
 4    },
 5    "@id": "https://index.example.org/id/org/x",
 6    "@type": "Organization",
 7    "address": {
 8        "@type": "PostalAddress",
 9        "addressLocality": "Paris, France",
10        "postalCode": "F-75002",
11        "streetAddress": "38 avenue de l'Opera"
12    },
13    "email": "secretariat(at)example.org",
14    "name": "Organization X",
15    "description": "Description of org ...",
16    "telephone": "( 33 1) 42 68 53 00",
17    "url": "https://example.org/",
18    "member": [
19        {
20            "@id": "https://example.org/id/org/1",
21            "@type": "Organization",
22            "name": "Organization A",
23            "description": "Org A is a potential parent organization of Org X"
24        },
25        {
26            "@id": "https://orcid.org/0000-0002-2257-9127",
27            "@type": "Person"
28        }
29    ],
30    "identifier": {
31        "@id": "https://grid.ac/institutes/grid.475727.4",
32        "@type": "PropertyValue",
33        "description": "UN Department of Economic and Social Affairs Sustainable Development",
34        "propertyID": "https://registry.identifiers.org/registry/grid",
35        "url": "https://grid.ac/institutes/grid.475727.4"
36    }
37}

On the property membership#

Line 18-29 show the inclusion of a schema.org/member property. There are issues to note here both for consumers (aggregators) and providers (publishers). The Person type is show connected simply on a type and id. This provides the cleanest connection. If a member is added by type and id, as in the case of the “Organization A” link, there is the problem of additional triples being added. Here, the name and description properties are going to add triples to the OIH KG. In so doing, we run the risk or adding potentially un-authoritative information. The aggregator doesn’t know if triples here are or are not provided by an actor authoritative for those properties. This could be addresses with framing or validation workflows, or ignored. The prov elements stored could be leveraged to later track down sources, but don’t provide further information on the issue of authority.

It is recommended that best practice is to attempt to link only on ids (with a type in all cases) where possible. If you are connecting with a type, do not provide additional properties. In cases where such an id can not be provided, you may wish to fill out basic properties you can provide with confidence.

import json
from pyld import jsonld
import os, sys

currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils

with open("./graphs/organization.json") as dgraph:
    doc = json.load(dgraph)

context = {
    "@vocab": "https://schema.org/",
}

compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
../../_images/README_11_0.svg

Details: Indentifier#

For each profile there are a few key elements we need to know about. One key element is what the authoritative reference or canonical identifier is for a resource.

import json
from rdflib.extras.external_graph_libs import rdflib_to_networkx_multidigraph
from rdflib.extras.external_graph_libs import rdflib_to_networkx_graph
from pyld import jsonld
import graphviz
import os, sys

currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils

with open("./graphs/organization.json") as dgraph:
    doc = json.load(dgraph)

frame = {
  "@context": {"@vocab": "https://schema.org/"},
  "@explicit": "true",
  "@requireAll": "true",
  "@type":     "Organization",
  "identifier": ""
}

context = {
    "@vocab": "https://schema.org/",
}

compacted = jsonld.compact(doc, context)

framed = jsonld.frame(compacted, frame)
jd = json.dumps(framed, indent=4)
print(jd)

jbutils.show_graph(framed)
{
    "@context": {
        "@vocab": "https://schema.org/"
    },
    "@id": "https://index.example.org/id/org/x",
    "@type": "Organization",
    "identifier": {
        "@id": "https://grid.ac/institutes/grid.475727.4",
        "@type": "PropertyValue",
        "description": "UN Department of Economic and Social Affairs Sustainable Development",
        "propertyID": "https://registry.identifiers.org/registry/grid",
        "url": "https://grid.ac/institutes/grid.475727.4"
    }
}
../../_images/README_13_1.svg

References#