ListNode: access label and filter by language

Hello everybody,
I come again with a gravsearch question: is it possible to select a ListNode and request its label by a given language?

let’s say that I would like to change the following request to not name the ListNode <http://rdfh.ch/lists/0001/otherTreeList01> but pull a generic ?listNode and its label and filter the label’s language.

What would the gravsearch query then look like?

PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
PREFIX anything: <http://api.dasch.swiss/ontology/0001/anything/v2#>

CONSTRUCT {
  ?thing knora-api:isMainResource true .
  ?thing anything:hasOtherListItem ?list .
} WHERE {
  ?thing a knora-api:Resource .
  ?thing a anything:Thing .
  ?thing anything:hasOtherListItem ?list .
  ?list knora-api:listValueAsListNode <http://rdfh.ch/lists/0001/otherTreeList01> .
}

Is this what you want?

PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
PREFIX anything: <http://api.dasch.swiss/ontology/0001/anything/v2#>

CONSTRUCT {
  ?thing knora-api:isMainResource true .
  ?thing anything:hasOtherListItem ?listValue .
} WHERE {
  ?thing a knora-api:Resource .
  ?thing a anything:Thing .
  ?thing anything:hasOtherListItem ?listValue .
  ?listValue knora-api:listValueAsListNode ?listNode .
  ?listNode rdfs:label ?listNodeLabel .
  FILTER langMatches(lang(?listNodeLabel), "en")
}

It’s not currently supported in Gravsearch, but only because Gravsearch currently rejects the langMatches function, as well as the lang function in the complex schema. But we could allow these.

thanks Ben!

  • accessing label and filtering by language

But we could allow these.

That would be cool.

  • accessing list nodes

looking at the generic example:

PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
PREFIX anything: <http://api.dasch.swiss/ontology/0001/anything/v2#>

CONSTRUCT {
  ?thing knora-api:isMainResource true .
  ?thing anything:hasOtherListItem ?listValue .
} WHERE {
  ?thing a anything:Thing .
  ?thing anything:hasOtherListItem ?listValue .
}

gives the error:

{
    "knora-api:error": "org.knora.webapi.DataConversionException: IRI http://rdfh.ch/0001/thing_with_two_list_values/second_list_value is not a Knora value IRI",
    "@context": {
        "knora-api": "http://api.knora.org/ontology/knora-api/v2#"
    }
}

But that might be unrelated to my attempts to get to the node’s value and should be investigated on its own (should I submit a bug for that?).

So starting again replacing anything:hasOtherListItem for anything:hasListItem:

PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
PREFIX anything: <http://api.dasch.swiss/ontology/0001/anything/v2#>

CONSTRUCT {
  ?thing knora-api:isMainResource true .
  ?thing anything:hasOtherListItem ?listValue .
} WHERE {
  ?thing a anything:Thing .
  ?thing anything:hasListItem ?listValue .
}

we get that matching list :slight_smile:

Then going for the list node level:

PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
PREFIX anything: <http://api.dasch.swiss/ontology/0001/anything/v2#>

CONSTRUCT {
  ?thing knora-api:isMainResource true .
  ?thing anything:hasOtherListItem ?listValue .
  ?listValue knora-api:listValueAsListNode ?listNode .
} WHERE {
  ?thing a anything:Thing .
  ?thing anything:hasListItem ?listValue .

  ?listValue a knora-api:ListValue .
  ?listValue knora-api:listValueAsListNode ?listNode .
}

I get the error:

{
    "knora-api:error": "org.knora.webapi.GravsearchException: ?listNode is not allowed in a CONSTRUCT clause",
    "@context": {
        "knora-api": "http://api.knora.org/ontology/knora-api/v2#"
    }
}

IRI http://rdfh.ch/0001/thing_with_two_list_values/second_list_value is not a Knora value IRI

That’s a bug in the test data. The IRI should be http://rdfh.ch/0001/thing_with_two_list_values/values/second_list_value. I’ll fix it.

?listNode is not allowed in a CONSTRUCT clause

This is because a Gravsearch CONSTRUCT clause only specifies resources and values, not things below the value level. You just need:

PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
PREFIX anything: <http://api.dasch.swiss/ontology/0001/anything/v2#>

CONSTRUCT {
  ?thing knora-api:isMainResource true .
  ?thing anything:hasListItem ?listValue .
} WHERE {
  ?thing a anything:Thing .
  ?thing anything:hasListItem ?listValue .
  ?listValue knora-api:listValueAsListNode ?listNode .
}

If the response is in the complex schema, the returned list value should contain the IRI of the list node. If the response is in the simple schema, you’ll just get the label of the list node.

That’s a bug in the test data. […] I’ll fix it.

Thanks

This is because a Gravsearch CONSTRUCT clause only specifies resources and values, not things below the value level.

right, I remember reading that on gravsearch documentation

So:

  • in the complex schema, I can only access the ListValue.
  • but I need the the complex schema to filter ListNode labels per language
  • then I can’t see the answer to that query’s question in the result

Or am I missing something?

OK, I think maybe I didn’t understand your question. I thought you had several different list nodes, each in a different language, and you wanted a list value that points to a node that has a particular language. In this case, if we allow the necessary functions as I mentioned, you can ask Gravsearch for the list value, which contains the IRI of the list node, and then you can use the /admin/lists/nodes route to get more information about that list node.

Or is it like this: you have one list node with multiple labels, each in a different language, and you want Gravsearch to return the label in the selected language? But then I don’t understand: if you already know which list node you want, you don’t need Gravsearch for that. Just use the /admin/lists/nodes route to get the list node, and get the label in the language you want.

Or you can use the /v2/node route if that’s more convenient.

I think the idea is that the client is probably going to cache list information anyway, so Gravsearch just returns the list node IRI.

Or is it like this: you have one list node with multiple labels, each in a different language, and you want Gravsearch to return the label in the selected language?

Yes that’s the use case, getting a resource and its properties including the lists nodes (the resource has several list properties) in a given language and in a single request.

For the text properties, it is easy to filter by language and the question raised by our user was “can I do the same as for text values but on lists”.

But then I don’t understand: if you already know which list node you want, you don’t need Gravsearch for that.

Sorry about that, that’s just me trying to work out an example in a common space (ontology we both know on data we can both access). We don’t know the node we want.

Fair enough, we can work out caching of the lists, probably using knora-api-js-lib

“can I do the same as for text values but on lists”

But this isn’t the same situation. Each text value can have only one language, so it makes sense to filter text values by language. But each list value points to one list node that can have labels in multiple languages. You’re not getting a different list node (or a different list value) for a different language. So you need to get the label in a particular language from a cached list node, and that’s beyond the scope of Gravsearch. I think knora-api-js-lib can probably help you here.

Or you can use the /v2/node route if that’s more convenient.

I think the idea is that the client is probably going to cache list information anyway, so Gravsearch just returns the list node IRI.

Yes, JS lib caches list nodes (https://dasch-swiss.github.io/knora-api-js-lib/classes/cache_listnodev2cache.listnodev2cache.html). But it would only get the labels in the user’s preferred language.

I think lists are structures whose elements are identified by their IRIs, not by their labels. Labels make the list nodes human-readable, but they are not used to perform any actual actions in the API.

But a Gravsearch query can be built by showing the list nodes with their labels and let the user choose. In Gravsearch, the IRI is submitted submitted.