How should embedded entities be declared in the Type Index Registry?


#21

It may happen that the pod owner doesn’t yet have shapes of the kind the app needs. Also, the app may require the pod owner to reorganize existing indexes or shapes. All this may require some negotiation, maybe with a third party. None of this is in the spec (yet) but there’s no harm in thinking about it.


#22

In a linked data context I would assume open-world as a default. The document does not say anything about closed-world assumption. How can I assume the data linked from the type index be complete? Especially if “complete” is subjective and depends highly on the kind of application that is looking for data.


#23

You could assume it if the spec would enforce it. “Complete” would be objective to the type defined by the solid:forclass property.


#24

RDF types work differently to types on programming languages. So for example the type https://schema.org/Movie does not define completeness in any sense. All the properties may or may not occur on resources of that type. And further: all other rdf properties from any vocabulary might occur in addition to the ones officially listed by schema.org.


#25

Coming back to the original question, I would do it like this:

https://pod.example.com/movies/spirited-away :

@prefix : <#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix schema: <https://schema.org/>.

:it
    schema:Movie;
    schema:name "Spirited Away".
:watch-action
    a schema:WatchAction;
    schema:object :it.

And in the type index:

<#movies> a solid:TypeRegistration;
    solid:forClass schema:Movie;
    solid:instanceContainer </movies/>.

<#watch-actions> a solid:TypeRegistration;
    solid:forClass schema:WatchAction;
    solid:instanceContainer </movies/>.

#26

I am not sure it that is legit. But you could try somthing like this:

@prefix :       <#> .
@prefix movies: <./> .
@prefix ldp:    <http://www.w3.org/ns/ldp#> .
@prefix schema: <http://schema.org/> .

movies:spirited-away
    a                      ldp:Resource,
                           schema:Movie ;
    schema:name            "Spirited Away" ;
    schema:potentialAction [
                               schema:WatchAction [ schema:agent <https://alice.com/profile/card#me> ; ] ;
                           ] ;
.

#27

Haha, I was just thinking the same, we drifted away :grin:


#28

I think this way you are saying, that alice might potentially watch the movie, but not that she did it, so it is something different


#30

Ah, you’re right. I missed that :see_no_evil:


#31

Ok thanks, that’s what I’ll do :).

I thought documents needed to have one “main entity” given the ldp:contains property pointing to the url, but it makes sense that they define only the document and not the entities defined inside.

This actually explains why the information that comes with the container request about its resources is only this:

movies:spirited-away
    a turtle:Resource, ldp:Resource;
    terms:modified "2020-04-13T13:53:30Z"^^XML:dateTime;
    posix:mtime 1586786010.248;
    posix:size 673.

Instead of:

movies:spirited-away
    a turtle:Resource, ldp:Resource, schema:Movie;
    terms:modified "2020-04-13T13:53:30Z"^^XML:dateTime;
    posix:mtime 1586786010.248;
    posix:size 673.

I still think it’s difficult to match actions with movies without crawling all the documents in a pod, but it won’t be a problem for my application if I assume they are in the same document as the movie. It’s semantically correct so at least other apps would understand it.


#32

Why do you have to assume they are in the same document?

You can just “follow your nose”. In ldflex I would do it like this:

const movie = await data["https://pod.example.com/movies/spirited-away#watch-action"].schema_object;
const movieName = await data[movie].schema_name;

This code will work no matter if the movie URI base on the same document, or completely somewhere else.

I would not like it, if your app breaks, when I reorganize my data and seperate the watch actions from the movies :wink:


#33

I like the idea of “following my nose”, but that’s why I raised concerns with movies not pointing to watch actions, only actions pointing to movies. Imagine I have a movie (so everything I know is https://pod.example.com/movies/spirited-away). How would I know where to look for a watch action If I don’t assume it’s on the same document?

In your example you are starting with the action. But my application will browse movies, not actions so the trail my nose will follow starts with a movie.

The reason why I have them inside of the same document is because I want to avoid doing too many requests, specially if I have to wait for one to finish to find the url of the next document.


#34

It is totally fine to place it in the same document. What I am saying is, you must not assume it will always be there.

But there is another thing to differ. As already mentioned the thing is not the same as the document about the thing. This also means, there may be several documents containing statements about a thing. Therefore it is totally possible to place the watch action into a document of it’s own, and still have a statement that relates Movie and WatchAction in the movie document.

Example:

https://pod.example.com/movies/spirited-away :

@prefix : <#>.
@prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix schema: <https://schema.org/>.

:it
    schema:Movie;
    schema:name "Spirited Away".

</watch-actions/watched-spirited-away#it>
    schema:object :it.

In turtle there is no need for a “reverse property” like in JSON-LD, because statements can be made in any direction anyway. You can “follow your nose” backwards, by looking for a schema:object relation, where the movie is the object instead of the subject. This works, no matter if the watch-action is “fully” described in the same document or in a document of it’s own. Of course the latter involves an additional request, but it is far from “crawling all the documents in a pod”.


#35

I just took a look at ldflex and think it is possible to actually use @reverse properties in a custom context. If you do so following your nose starting from the watch-action would not be any different:

const watchAction = await data["https://pod.example.com/movies/spirited-away#it"].schema_object_of;
const agent = await data[watchAction].schema_agent;

Be aware that this only affects the querying, not how the data is stored as turtle!


#36

Ok, in this case I’d be assuming that at least the schema:object property of the watched action is in the same document right?

So this:

Would still happen. If you remove the action, including it’s schema:object property, it’s not entirely wrong that my application stops working?


#37

In short: yes, agreed.

But let me frame it differently to explain my reasoning:

</watch-actions/watched-spirited-away#it>
    schema:object :it.

I do not call this “property of the watch action”. It is a statement linking the movie to the watch-action. It is a statement about the watch action and it is a statement about the movie as well. If you remove it from the movie document you are removing a statement about the movie, so yes, this might break things, because I stop applications from following their nose by removing it.