json-ld / json-ld.org

JSON for Linked Data's documentation and playground site
https://json-ld.org/
Other
859 stars 152 forks source link

"Stratified" or "Dictionaried" API feature #460

Closed jmatsushita closed 6 years ago

jmatsushita commented 7 years ago

Hi there,

I was looking for a way to access properties in a JSON-LD document based on triples (to patch the document). This would mean having a view which creates a dictionary for a given document. The term Normalisation is already used, but this approach would be close to the way https://github.com/paularmstrong/normalizr. D3 uses https://github.com/d3/d3-hierarchy/blob/master/README.md#stratify in a slightly different way but with the same general intent.

The goal would be to be able to address document values with this syntax stratified_doc[triple.subject][triple.predicate] or even better stratified[triple.graph][triple.subject][triple.predicate].

This could also be a @stratified parameter for expansion.

Example

For a document:

{
  "@context": {
    "dc": "http://purl.org/dc/elements/1.1/",
    "ex": "http://example.org/vocab#",
    "xsd": "http://www.w3.org/2001/XMLSchema#",
    "ex:contains": {
      "@type": "@id"
    }
  },
  "@id": "http://example.org/graph/0",
  "dc:creator": "Jane Doe",
  "@graph": [
    {
      "@id": "http://example.org/library",
      "@type": "ex:Library",
      "ex:contains": "http://example.org/library/the-republic"
    }
  ]
}

Such a stratified would therefore look like:

{
  "http://example.org/graph/0": {
   "http://example.org/library": {
      "@type": "http://example.org/vocab#Library",
      "http://example.org/vocab#contains": {
        "@id": "http://example.org/library/the-republic"
      }
    },
    "http://example.org/library/the-republic": {}
  },
  "@graph": {
    "http://example.org/graph/0": {
      "http://purl.org/dc/elements/1.1/creator": "Jane Doe"
    }
  }
}

This would therefore allow to do the following:

// Access a triple from the default graph
var creator = stratified['@graph']['http://example.org/graph/0']['http://purl.org/dc/elements/1.1/creator'];
// "Jane Doe"

// Access a triple in a named graph
var type = stratified['http://example.org/graph/0']['http://example.org/library']['@type'];
// "http://example.org/vocab#Library"

// Before submitting a document, mutate a property
stratified['http://example.org/graph/0']['http://example.org/library/the-republic']['@type'] = 'http://example.org/vocab#Book';

// Or using an immutable spread syntax approach
var new_doc = { 
  ...stratified, 
  'http://example.org/graph/0': {
    ...stratified['http://example.org/graph/0'],
    'http://example.org/library/the-republic' : {
      ...stratified['http://example.org/graph/0']['http://example.org/library/the-republic'],
      '@type': 'http://example.org/vocab#Book'
    }
  }
}
gkellogg commented 7 years ago

This looks similar to the @id maps feature that was added recently (see Node Identifier Indexing. But, that hasn't been extended to graphs quite yet. There is a separate issue on an @graph container #195. You might look at these in the current spec drafts to see how they might handle your use case.

lanthaler commented 7 years ago

Some JSON-LD processors already allow you to access data in such a way. Niklas also wrote down the Connect draft a while ago

gkellogg commented 7 years ago

Framing also has @embed: @link for in-memory use, although I'm not sure it belongs as part of the core framing algorithm.