Skip to content

JSON-LD 1.1: method to require {"id": "uri"} resource compaction result #507

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

Closed
azaroth42 opened this issue Jun 5, 2017 · 8 comments
Closed
Labels
api defer Issue deferred to future Working Group

Comments

@azaroth42
Copy link
Contributor

Issue: The compaction algorithm prefers the most compact format, which for resources without relationships is a string containing the URI. This causes problems in systems that cannot handle arrays of mixed data types (for example ElasticSearch) when there are also resources that have relationships, resulting in both objects and strings in the same array.

For example:

"seeAlso": [
    "http://example.org/reference1",
    {"id": "http://example.org/reference2", "format": "text/html"}
  ]

would raise an error in Elastic.

Proposed solution: Provide a flag to the compaction algorithm to signal that the resulting JSON should always create objects for resources, even if there is only the URI available. This would instead render the example above as an array of objects:

"seeAlso": [
    {"id": "http://example.org/reference1"},
    {"id": "http://example.org/reference2", "format": "text/html"}
  ]
@gkellogg
Copy link
Member

gkellogg commented Jul 1, 2017

A compaction flag seems pretty heavy-handed, and could have some unintended consequences. I'd rather see if there might be something that could be done on the term definition to handle this.

Basically, it seems that if a term could be defined which would be selected for any kind of value that would not conflate the compaction semantics. Right now, term selection is based on container and type/language, and a term won't be selected unless it matches the attributes of a given value. Those attributes are also called into play when compacting.

PR #510 addresses a similar concern where an empty list would not be compacted using a list term because it had no values to determine if it should compact for a given language or type. We might consider allowing @any to be the value of @type in a term definition, which could allow the term to be selected for any value type, but would not trigger compaction of such values in the Compaction Algorithm. This likely would require more tweaks to IRI Compaction and Term Selection, at least.

I'm not advocating for this change myself, but I'd like to see how much support such a change might get.

@gkellogg gkellogg added the api label Jul 1, 2017
@azaroth42
Copy link
Contributor Author

Agreed that a flag is probably overkill. A keyword in the context is sufficient for our use case at least, though it would be nice if it required a resource and fell through for literals so that it didn't select them in compaction (per discussion in #510)...

Thus, something like:

{
  "@context": {
    "id": "@id",
    "rdfs": {"@id": "http://.../", "@prefix": true},
    "seeAlso": {"@id": "rdfs:seeAlso", "@type": "@someresource", "@container": "@set"}
  },
  "seeAlso": [
    {
      "id": "http://example.org/reference1"
    }
  ]
}

(And a triple _:x rdfs:seeAlso "string" would not compact to seeAlso as the object of the triple doesn't match @someresource)

@azaroth42 azaroth42 changed the title JSON-LD 1.1 Request: Flag to allow {"id": "uri"} compaction result JSON-LD 1.1: method to require {"id": "uri"} resource compaction result Jul 5, 2017
@niklasl
Copy link
Member

niklasl commented Jul 5, 2017

In the given example case, doesn't this happen since seeAlso is (I assume) declared in the context with @type: @id (or @type: @vocab)? Otherwise, the values should always be node objects even when compacted. (They would not be recognized as IRIs otherwise.)

If so, this shape is under your control through the context, so just removing the @type for seeAlso should result in the predictable shape.

In a more general case where IRIs and literals are mixed for the same property, the problem does remain. I think it can be alleviated by using a different term for the property + literal combo, but only if their type can be predicted. Otherwise, the "elastic problem" might have to be solved using some new mechanism, so that the value is always an object, even for plain literals (i.e. given with a @value key). I could imagine an option akin to compactArrays, e.g. compactLiterals (defaulting to true). (I'd probably prefer for both of these to be controlled within the context though...)

(Note that while compaction does not (IIRC) provide this option, it is valid JSON-LD to give plain literals as objects with a @value key. So you could get around the specific technical hurdle by e.g. a post-processing step...)

@azaroth42
Copy link
Contributor Author

Agree that removing the @type completely would currently produce the desired representation of always creating a JSON object for the resource... but it seems like a kludge to rely on omitting known information in order to produce a result, and an explicit solution would be better. Hence the initial thought of a compaction flag.

It would also not be "backwards compatible" with other data produced using the context before the change, which would be helpful if not essential. A separate keyword to control it would be expensive but fallback nicely to existing behavior.

@gkellogg
Copy link
Member

gkellogg commented Jul 5, 2017

All mechanism to avoid compacting to a string form end up failing, because the compaction algorithm always attempts to do this, and the term selection process avoids selecting a term that doesn't match. In retrospect, conflating term selection and compaction results may be the issue, and we should have probably simply gone with the first term that matches the property URI without regard to the shape of the data (which would substantially simplify that logic, anyway). I think the next best thing we could do is to define something in the term definition that causes it to match any shape data, and simply avoid conflicting terms in the context. The "@type": "@any" sort of addresses this, but then prohibits compaction to string.

  1. We could radically change term selection in 1.1, and simply select the first term found (using the existing mechanism (This would simplify term selection and disassociate it with value matching):

    ordered by length, shortest first (ties are broken by choosing the lexicographically least term).

  2. Add some property to the term definition (e.g. "@matchAll": true) that does this disassociation.

To address the compaction to string, we'd need to add yet something else to an expanded term definition, say "@compact": false.

Of course, I think we're straying pretty far from 1.0 now, and this is probably too consequential for a CG to do, and would be better for a JSON-LD 2.0 which probably needs a separate charter.

The best course is probably going to be to rely on a certain amount of client flexibility, and simply rely on the untyped term definitions to accomplish this.

@azaroth42
Copy link
Contributor Author

azaroth42 commented Jul 5, 2017

conflating term selection and compaction results may be the issue

👍

The best course is ... rely on the untyped term definitions to accomplish this.

I think that's probably the case for 1.x.

Do we have a defer or postpone label to say that this issue is ignorable until much later?

@gkellogg
Copy link
Member

gkellogg commented Jul 5, 2017

We have on-hold, which I just applied.

@gkellogg gkellogg added defer Issue deferred to future Working Group and removed on-hold labels Apr 4, 2018
@gkellogg
Copy link
Member

gkellogg commented Jul 8, 2018

Transfered to the WG: w3c/json-ld-api#6

@gkellogg gkellogg closed this as completed Jul 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api defer Issue deferred to future Working Group
Projects
None yet
Development

No branches or pull requests

3 participants