Skip to content
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

Recursive index map of index maps #826

Open
grenik opened this issue Nov 7, 2023 · 4 comments
Open

Recursive index map of index maps #826

grenik opened this issue Nov 7, 2023 · 4 comments

Comments

@grenik
Copy link

grenik commented Nov 7, 2023

Is there a way to model map of maps?

I see only single-level maps: Property-based data indexing

But maps often have 2+ levels of indexing. Simplified example: animals are indexed by the size, and then by the color.

{
  "@context": {
    "schema": "http://schema.org/",
    "map": {
      "@id": "schema:animals",
      "@type": "@id",
      "@container": "@index",
      "@index": ["schema:size", "schema:color"]
    },
  },
  "map": {
    "small": {
      "green": "schema:Frog",
      "black": "schema:Ant"
    },
    "medium": {
      "black": "schema:Raven"
    },
    "big": {
      "green": "schema:Crocodile"
    }
  }
}

expansion result:

[
  {
    "http://schema.org/animals": [
      {
        "@id": "http://schema.org/Frog",
        "http://schema.org/size": [{"@value": "small"}],
        "http://schema.org/color": [{"@value": "green"}]
      },
      {
        "@id": "http://schema.org/Ant",
        "http://schema.org/size": [{"@value": "small"}],
        "http://schema.org/color": [{"@value": "black"}]
      },
      {
        "@id": "http://schema.org/Raven",
        "http://schema.org/size": [{"@value": "medium"}],
        "http://schema.org/color": [{"@value": "black"}]
      },
      {
        "@id": "http://schema.org/Crocodile",
        "http://schema.org/size": [{"@value": "big"}],
        "http://schema.org/color": [{"@value": "green"}]
      }
    ]
  }
]
@gkellogg
Copy link
Member

gkellogg commented Nov 7, 2023

Without going into your examples too far, you might look at Nested Properties which an allow nesting at arbitrary depth.

@grenik
Copy link
Author

grenik commented Nov 8, 2023

Nested properties require that I know their names and define them explicitly in the @context, but in my case I receive JSONs with arbitrary properties: an indexed maps nested inside another indexed map (callbacks in my example are first indexed by the callback name and then by a path). I need to convert property names (the keys used to index objects) to RDF property values.

I can achieve it using Property-based data indexing via @container: @indexand @index: URI, but only for one level, while the data I receive often contain multi-level maps, as shown in my examples.

Specification can be extended to model my case by allowing array values for @index:

{
  "@context": {
    "mapWith2LevelsAndSemanticKeys": {
      "@id": "...",
      "@container": "@index",
      "@index": ["schema:firstLevelKey", "schema:secondLevelKey"] // this already tells JSON-LD processor that map has 2 levels
    },
  }
}

If keys at certain levels can be ignored (have no semantic meaning), this could also be modelled by placing nulls in @index.

{
  "@context": {
    "mapWithFourLevels": {
      "@id": "...",
      "@container": "@index",
      "@index": [null, "schema:secondLevelKey", null, "schema:fourthLevelKey"] // skip keys on level 1 and 3
    },
  }
}

@grenik
Copy link
Author

grenik commented Nov 9, 2023

Real-life example:

For instance, callbacks in OpenAPI are first indexed by the callback name and then by the path (see spec, example)

Here is a simplified example of an API description with a single-level map pahts and a 2-level map callbacks:

{
  "paths": {
    "/registration": {
      "post": "registers user",
      "delete": "deletes account"
    },
    "/login": {
      "post": "login",
      "delete": "logout"
    }
  },
  "callbacks": {
    "Registration Callback": {
      "/onRegistration": {
        "post": "called when registered",
        "delete": "called when account is deleted"
      }
    },
    "Login Callback": {
      "/onLogin": {
        "post": "when logged in"
      },
      "/onLogout": {
        "post": "when logged out"
      }
    }
  }
}

@BigBlueHat
Copy link
Member

@grenik sadly at this point, I don't think JSON-LD can support that structure. You'd need to convert it into something with less "implied"/structural semantics.

@gkellogg this is certainly a common case in human-facing JSON (well...YAML...) formats like OpenAPI, so I do wonder what it would take to support it. Everything I can imagine right now looks rather odd in the context definition, but maybe there's a way we could explore for doing multiple "stacked" indexes somehow. Something fun to explore, anyhow. 😀

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

No branches or pull requests

3 participants