New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How is @graph going to be used/supported in framing? #118

Closed
lanthaler opened this Issue May 10, 2012 · 15 comments

Comments

Projects
None yet
3 participants
@lanthaler
Member

lanthaler commented May 10, 2012

We haven't discussed yet how @graph can be used in framing. I think we should do the following:

  • if @graph isn't used in the frame (till that point), the input (subject map) to the framing algorithm is the merge of all graphs in the input document
  • the first use of @graph without an @id will use the default graph (this has to be specified a bit better)
  • all other uses of @graph will use the specified named graph (what happens if no @id was set?)

Thoughts?

@gkellogg

This comment has been minimized.

Member

gkellogg commented May 10, 2012

I had some thoughts on this on the mailing list before: http://lists.w3.org/Archives/Public/public-linked-json/2012Apr/0036.html:

Although the framing algorithm hasn't been documented adequately, it's been implemented by both Dave and myself. However, our addition of named graphs has added some complications. (Note that algorithms for from/to RDF have already been updated, and expansion/compaction required only minimal changes..

The basic issue is that framing works by first flattening the document to an array of JSON objects in expanded form. Given that the @graph bit is required structure, we can't simply do that (usually). Also, the existence of named graphs implies other usage patterns where we may want to select based on graph membership, in addition to type and property.

My first suggestion is that, by default, framing flattens named graphs into a single default graph, so that the existing algorithm works as is. For many respects, this is what people want to do anyway, so by default, I'd suggest that we just leave the algorithm as is, with the exception that @graph contents, which would otherwise just contain references to the named objects, would be removed.

Consider the following document (test fromRdf-0005.jsonld):

[[{
 "@id": "http://example.com/U",
 "@graph": [
   {
     "@id": "http://example.com/Subj1",
     "@type": ["http://example.com/Type"],
     "http://example.com/ref": [{"@id": "http://example.com/U"}],
     "http://example.com/list": {
       "@list": [
         {"@value": "a"},
         {"@value": "b"}
       ]
     }
   }
 ],
 "@type": ["http://example.com/Graph"],
 "http://example.com/name": [{"@value": "Graph"}]
}]

This has a default graph, containing , and a graph named that includes . As it is now, this would be flattened to the following:
I would suggest that this would be something like the following after basic framing:

[
 {
   "@id": "http://example.com/U",
   "@type": ["http://example.com/Graph"],
   "http://example.com/name": [{"@value": "Graph"}]
 },
   {
     "@id": "http://example.com/Subj1",
     "@type": ["http://example.com/Type"],
     "http://example.com/ref": [{"@id": "http://example.com/U"}],
     "http://example.com/list": {
       "@list": [
         {"@value": "a"},
         {"@value": "b"}
       ]
     }
   }
]

Then, normal framing can operate on all elements as it does today.

However, given named graphs, people will probably want to do different types of queries. you might imagine a frame such as the following:

{
"@graph": null,
"@type": {}
}

This could return only subjects (with @type) in the default context and return something like the following:

[
 {
   "@id": "http://example.com/U",
   "@type": ["http://example.com/Graph"],
   "http://example.com/name": [{"@value": "Graph"}]
 }
]

Or,

{
 "@graph": {},
 "@type": {}
}

which could return all named graphs and could be something like the following:

[[{
 "@id": "http://example.com/U",
 "@graph": [
   {
     "@id": "http://example.com/Subj1",
     "@type": ["http://example.com/Type"],
     "http://example.com/ref": [{"@id": "http://example.com/U"}],
     "http://example.com/list": {
       "@list": [
         {"@value": "a"},
         {"@value": "b"}
       ]
     }
   }
 ],
}]

(note that the properties of the referring element are gone.)

There could be various combinations of these. If a frame includes @graph, then flattening would preserve the @graph structure when flattening the graph, maintaining parralel structures at the base for subjects in the un-named graph, and the same flattening structure within each @graph. This should allow the flattening algorithm to work recursively on each graph and require only relatively small changes.

Specifying a @id along with @graph could limit the results to only the graph with the specified ID. In this case, it might remove the named context, and just give the content of @graph.

@lanthaler

This comment has been minimized.

Member

lanthaler commented May 11, 2012

I probably missed that mail as I was travelling at that time. It think that's in line with what I proposed above. The frame would implicitely start with a "@graph": null.

I haven't had time yet to fully implement framing but I implemented the subject map generation algorithm and I just pushed an update to support multiple graphs. I chose to add another layer in the subject map which defines the graph, so instead of subjectMap.subject it is now subjectMap.graph.subject.

For the default graph I use @graph (would you prefer @default?) as the key, @merged for the merged graph, and otherwise the graph's IRI. If you are happy with that change, I can update the subject mapping algorithm in the spec accordingly.

Just to make sure I didn't miss something. Taking this as an input:

{
  "@context": {
    "foaf": "http://xmlns.com/foaf/0.1/",
    "ex": "http://property.com/"
  },
  "@graph": [
    {
      "@id": "http://example.com/default/1",
      "foaf:name": "Default 1",
      "foaf:knows": {
        "@id": "http://example.com/default/2"
      }
    },
    {
      "@id": "http://example.com/default/2",
      "foaf:name": "Default 2",
      "foaf:knows": {
        "@id": "http://example.com/graphA/2"
      }
    },
    {
      "@id": "http://example.com/default/3",
      "ex:refNamedGraph": {
        "@id": "http://example.com/graphA",
        "ex:author": "Graph Author A",
        "@graph": [
          {
            "@id": "_:graphA/1",
            "foaf:name": "GraphA 1",
            "foaf:knows": {
              "@id": "http://example.com/graphA/2"
            }
          },
          {
            "@id": "http://example.com/graphA/2",
            "foaf:name": "GraphA 2",
            "foaf:knows": {
              "@id": "http://example.com/default/1",
              "foaf:name": "Default 1 from Graph A"
            }
          }
        ]
      }
    }
  ]
}

This is will be the output of the subject map generation (you basically run the algorithm again to create the merged graph):

{
  "@graph": {
    "http://example.com/default/1": {
      "@id": "http://example.com/default/1",
      "http://xmlns.com/foaf/0.1/name": [ { "@value": "Default 1" } ],
      "http://xmlns.com/foaf/0.1/knows": [ { "@id": "http://example.com/default/2" } ]
    },
    "http://example.com/default/2": {
      "@id": "http://example.com/default/2",
      "http://xmlns.com/foaf/0.1/name": [ { "@value": "Default 2"  } ],
      "http://xmlns.com/foaf/0.1/knows": [ { "@id": "http://example.com/graphA/2" } ]
    },
    "http://example.com/graphA/2": {
      "@id": "http://example.com/graphA/2"
    },
    "http://example.com/default/3": {
      "@id": "http://example.com/default/3",
      "http://property.com/refNamedGraph": [ { "@id": "http://example.com/graphA" } ]
    },
    "http://example.com/graphA": {
      "@id": "http://example.com/graphA",
      "http://property.com/author": [ { "@value": "Graph Author A" } ]
    }
  },
  "http://example.com/graphA": {
    "_:t0": {
      "@id": "_:t0",
      "http://xmlns.com/foaf/0.1/name": [ { "@value": "GraphA 1" } ],
      "http://xmlns.com/foaf/0.1/knows": [ { "@id": "http://example.com/graphA/2" } ]
    },
    "http://example.com/graphA/2": {
      "@id": "http://example.com/graphA/2",
      "http://xmlns.com/foaf/0.1/name": [ { "@value": "GraphA 2" } ],
      "http://xmlns.com/foaf/0.1/knows": [ { "@id": "http://example.com/default/1" } ]
    },
    "http://example.com/default/1": {
      "@id": "http://example.com/default/1",
      "http://xmlns.com/foaf/0.1/name": [ { "@value": "Default 1 from Graph A" } ]
    }
  },
  "@merged": {
    "http://example.com/default/1": {
      "@id": "http://example.com/default/1",
      "http://xmlns.com/foaf/0.1/name": [
        { "@value": "Default 1" },
        { "@value": "Default 1 from Graph A" }
      ],
      "http://xmlns.com/foaf/0.1/knows": [ { "@id": "http://example.com/default/2" } ]
    },
    "http://example.com/default/2": {
      "@id": "http://example.com/default/2",
      "http://xmlns.com/foaf/0.1/name": [ { "@value": "Default 2" } ],
      "http://xmlns.com/foaf/0.1/knows": [ { "@id": "http://example.com/graphA/2" } ]
    },
    "http://example.com/graphA/2": {
      "@id": "http://example.com/graphA/2",
      "http://xmlns.com/foaf/0.1/name": [ { "@value": "GraphA 2" } ],
      "http://xmlns.com/foaf/0.1/knows": [ { "@id": "http://example.com/default/1" } ]
    },
    "http://example.com/default/3": {
      "@id": "http://example.com/default/3",
      "http://property.com/refNamedGraph": [ { "@id": "http://example.com/graphA" }
      ]
    },
    "http://example.com/graphA": {
      "@id": "http://example.com/graphA",
      "http://property.com/author": [ { "@value": "Graph Author A" } ]
    },
    "_:t0": {
      "@id": "_:t0",
      "http://xmlns.com/foaf/0.1/name": [ { "@value": "GraphA 1" } ],
      "http://xmlns.com/foaf/0.1/knows": [ { "@id": "http://example.com/graphA/2" } ]
    }
  }
}

lanthaler added a commit that referenced this issue May 17, 2012

Update subject map generation algorithm to fix bugs and handle multip…
…le graphs

The current subject map generation algorithm didn't handle multiple graphs and had some bugs. This update includes full support for @graph and fixes those bugs. If the values of @type would be expanded to @id objects (issue #118), this algorithm could be further simplified.

This addresses #124. Since the bug is also in the playground I do not close this issue yet.
@lanthaler

This comment has been minimized.

Member

lanthaler commented May 19, 2012

@gkellogg , after re-reading your mail I came to the conclusion that you had something else in mind. You were using @graphto identify the graph to use which is not what we do in JSON-LD documents. @graph contains the graph, but it is @id which names it. So I think to support named graphs you would have to insert an "intermediary" object in the frame like:

{
  "ex:contains": {
    "@id": "IRI of the named graph",
    "@graph": {}                    <-- wildcard, all objects in that graph will be returned
  }
}

If there's a match, this would result in something like

{
  "ex:contains": {
    "@id": "IRI of the named graph",
    "@type": "ex:graph",            <-- other properties of the named graph
    "@graph": [
        ... contents of graph ...
    ]
  }
}
@gkellogg

This comment has been minimized.

Member

gkellogg commented May 19, 2012

It's getting hard to really see whats going on. We needed simpler examples. A top-level object with @id and @graph creates a named graph. The framing syntax should do the same. Being able to specify a value for @id to get some specific named graph would be useful, or matching on @type of the object containing a graph, if the @graph keyword is provided.

We should probably start from our requirements for framing graphs, and see what is the least change to framing we can make to do that.

@lanthaler

This comment has been minimized.

Member

lanthaler commented May 19, 2012

OK, let me try to explain what I have in mind based on the Library example where I added a named graph:

{
  "@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/library",
  "dc:name": "Library",
  "@type": "ex:Library",
  "ex:contains": {
    "@id": "http://example.org/graphs/books",
    "@graph": {
      "@id": "http://example.org/library/the-republic",
      "@type": "ex:Book",
      "dc:creator": "Plato",
      "dc:title": "The Republic",
      "ex:contains": {
        "@id": "http://example.org/library/the-republic#introduction",
        "@type": "ex:Chapter",
        "dc:description": "An introductory chapter on The Republic.",
        "dc:title": "The Introduction"
      }
    }
  }
}

So we have the default graph containing a library which references the graph http://example.org/graphs/books which in turn contains a book. The book contains a chapter (no named graph there).

So, a frame (omitting the context) like

{
  "@type": "ex:Library",
  "ex:contains": {
    "@id": "http://example.org/graphs/books",
    "@graph": {}
  }
}

Should in IMO return this (again omitting the context):

{
  "@graph": [
    {
      "@id": "http://example.org/library",
      "dc:name": "Library",
      "@type": "ex:Library",
      "ex:contains": {
        "@id": "http://example.org/graphs/books",
        "@graph": [
          {
            "@id": "http://example.org/library/the-republic",
            "@type": "ex:Book",
            "dc:creator": "Plato",
            "dc:title": "The Republic",
            "ex:contains": { "@id": "http://example.org/library/the-republic#introduction" }
          },
          {
            "@id": "http://example.org/library/the-republic#introduction",
            "@type": "ex:Chapter",
            "dc:description": "An introductory chapter on The Republic.",
            "dc:title": "The Introduction"
          }
        ]
      }
    }
  ]
}

Is this what you have in mind as well?

@lanthaler

This comment has been minimized.

Member

lanthaler commented May 22, 2012

RESOLVED: Defer @graph and, in general, value matching from the framing algorithm.

@lanthaler

This comment has been minimized.

Member

lanthaler commented May 27, 2012

Gregg, I would appreciate if you could have a look at my implementation of this. Is this in line with what you had in mind?

lanthaler added a commit that referenced this issue Aug 29, 2012

@lanthaler

This comment has been minimized.

Member

lanthaler commented Sep 4, 2012

RESOLVED: Do not support .frame() in JSON-LD 1.0 API.

@paolociccarese

This comment has been minimized.

paolociccarese commented Apr 7, 2014

I am developing back-end technology for supporting Open Annotation and I am normally making heavy use of Named Graphs for supporting Micropublications, Nanopublications and other structured types of annotation. I was wondering if there is a chance you would reconsider adding framing support for Named Graphs. I would be more than happy to contribute use cases and examples.

@lanthaler

This comment has been minimized.

Member

lanthaler commented Apr 7, 2014

@paolociccarese, my JSON-LD processor (JsonLD, written in PHP) already supports it. The framing spec, however, is completely outdated. I'm sure no one is opposed to support named graphs in framing but it will probably take some more time till we start working on framing again. Are you interested in this for a specific implementation or just raising it as a general comment/feature request?

@paolociccarese

This comment has been minimized.

paolociccarese commented Apr 7, 2014

@lanthaler I am using the JSON-LD processor for Java https://github.com/jsonld-java/jsonld-java that is now integrated in Jena. I would also raise that as a general feature request as in scientific environments we do use heavily Named Graphs.

@gkellogg

This comment has been minimized.

Member

gkellogg commented Apr 7, 2014

@paulociccarrese, as @lanthaler said, it's really just a matter of time before the CG will get to this. Someone stepping up with concrete use cases, and better still, an updated framing algorithm, would help quite a bit!

@lanthaler

This comment has been minimized.

Member

lanthaler commented Apr 7, 2014

OK, perhaps you should then raise an issue for jsonld-java as well.. adding this to the current framing implementation should be quite trivial.

@paolociccarese

This comment has been minimized.

paolociccarese commented Apr 7, 2014

@lanthaler I will add a feature request there as currently the specs say "Presently, it only works for documents without named graphs.", so I am guessing is not really an issue. @gkellogg I have some use cases and examples, where can I post them?

@gkellogg

This comment has been minimized.

Member

gkellogg commented Apr 7, 2014

Sending them to public-linked-json@w3.org will get good visibility and additional discussion. The could also be linked to this issue, and should probably go in the spec at some point. You could consider updating the framing spec and adding use cases directly there; we can pull them back in from your fork.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment