kazarena / json-gold

A JSON-LD processor for Go
Apache License 2.0
114 stars 17 forks source link

Force Nesting #3

Closed scisci closed 9 years ago

scisci commented 9 years ago

Hi Kazarena, this may be a limitation of json-ld, but I have a json-ld object below. I generate this object by going from RDFDataset to using api.FromRDF(). In order to make it more succinct, it would be nice if instead of having an array of objects here, I could express it as a single object, with :b1 nested inside :b0. Do you know of any json-ld calls that will achieve that? I tried compact, but didn't work.

[
  {
    "@id": "_:b0",
    "@type": [
      "http://www.cidoc-crm.org/cidoc-crm/E15_Identifier_Assignment"
    ],
    "http://www.cidoc-crm.org/cidoc-crm/P140_assigned_attribute_to": [
      {
        "@id": "http://www.verisart.com/objects/e7822ade-0a3a-493c-8e83-16580ce8e866"
      }
    ],
    "http://www.cidoc-crm.org/cidoc-crm/P141_assigned": [
      {
        "@id": "_:b1"
      }
    ]
  },
  {
    "@id": "_:b1",
    "@type": [
      "http://www.cidoc-crm.org/cidoc-crm/E35_Title"
    ],
    "http://www.w3.org/2000/01/rdf-schema#label": [
      {
        "@language": "en",
        "@value": "Mona Lisa"
      }
    ]
  }
]
kazarena commented 9 years ago

Hi @scisci,

It looks like a good case to use JSON-LD Framing.

See examples in the official test suite:

https://github.com/kazarena/json-gold/blob/master/ld/testdata/frame-0001-in.jsonld https://github.com/kazarena/json-gold/blob/master/ld/testdata/frame-0001-frame.jsonld https://github.com/kazarena/json-gold/blob/master/ld/testdata/frame-0001-out.jsonld

In this example we have a library, a book and a chapter:

{
  "@context": {
    "dc": "http://purl.org/dc/elements/1.1/",
    "ex": "http://example.org/vocab#",
    "ex:contains": {"@type": "@id"}
  },
  "@graph": [
    {
      "@id": "http://example.org/test/#library",
      "@type": "ex:Library",
      "ex:contains": "http://example.org/test#book"
    },
    {
      "@id": "http://example.org/test#book",
      "@type": "ex:Book",
      "dc:contributor": "Writer",
      "dc:title": "My Book",
      "ex:contains": "http://example.org/test#chapter"
    },
    {
      "@id": "http://example.org/test#chapter",
      "@type": "ex:Chapter",
      "dc:description": "Fun",
      "dc:title": "Chapter One"
    }
  ]
}

And we would like to ensure that chapters are nested within books and books are nested within libraries. So we need to invoke frame operation with the following frame document:

{
  "@context": {
    "dc": "http://purl.org/dc/elements/1.1/",
    "ex": "http://example.org/vocab#"
  },
  "@type": "ex:Library",
  "ex:contains": {
    "@type": "ex:Book",
    "ex:contains": {
      "@type": "ex:Chapter"
    }
  }
}

It will then give us the following output:

{
  "@context": {
    "dc": "http://purl.org/dc/elements/1.1/",
    "ex": "http://example.org/vocab#"
  },
  "@graph": [{
    "@id": "http://example.org/test/#library",
    "@type": "ex:Library",
    "ex:contains": {
      "@id": "http://example.org/test#book",
      "@type": "ex:Book",
      "dc:contributor": "Writer",
      "dc:title": "My Book",
      "ex:contains": {
        "@id": "http://example.org/test#chapter",
        "@type": "ex:Chapter",
        "dc:description": "Fun",
        "dc:title": "Chapter One"
      }
    }
  }]
}

I believe you can solve your problem by using the same approach. However, as always, it's worth mentioning that JSON-LD is just JSON in the end and sometimes framing is a way too heavy solution for simple problems. I.e. if you are in full control of the input data and if its structure is reasonably static, it may be easier just to nest the nodes directly in JSON rather than relying on powerful but relatively expensive operations like framing.

See more discussion here

scisci commented 9 years ago

Yep that looks like what I was looking for, although I would also prefer to get rid of the graph property and have it as a single object. Thanks again for the help.

PS in the meantime I wrote some code that does the same thing (finds ids and nests, reducing down to a single object) but the framing method is probably more robust.

kazarena commented 9 years ago

Graph property is not required in the example above (because there's just one node inside) but it may be necessary for other documents. I can't remember exactly but there may be a configuration option to remove the graph in this case.

Based on my experience so far with JSON-LD, if there is a requirement to have your documents in a specific (e.g. pretty or minimalist) shape, you will most likely need to do some small post-processing of your JSON-LD document after applying standard transformations.