After learning the basics of SPARQL I'm still trying to make sense of 1:N relationships. How can I retrieve an object with all its relationships as a single record?
For example, I have a Project linked to two Topics. And I try to retrieve it with:
SELECT ?projName ?topic ?topicName {
?proj hasName ?projName .
?proj hasTopic ?topic .
?topic hasName ?topicName .
FILTER (?proj = <$uri>) .
}
But what I get is:
result: [
[
projName: "My Project"
topic: "TOPIC1_URI"
topicName: "First Topic"
],
[
projName: "My Project"
topic: "TOPIC2_URI"
topicName: "Second Topic"
]
]
But I would want to get it as:
result: [
projName: "My Project"
topics: [
[
topic: "TOPIC1_URI"
topicName: "First Topic"
],
[
topic: "TOPIC2_URI"
topicName: "Second Topic"
]
]
]
How could I achieve this? I don't know what I'm missing but I don't see how to do this with SPARQL.
Thanks a lot in advance
As you can read here, the result of a SELECT
SPARQL query is a set of bindings, i.e., assignments of values to the free variables of the query. You can think of such bindings as a matrix or a table, like for SQL queries, whose attributes are the variables' names. But you can't arrange such variables bindings as you wish if you have just a matrix for representing them.
What you can do is to collect all data about topics in a single variable using the GROUP_CONCAT
function. For example:
SELECT
?projName
(GROUP_CONCAT(?topicData; separator=", ") AS ?topics)
WHERE {
?proj hasName ?projName .
?proj hasTopic ?topic .
?topic hasName ?topicName .
FILTER (?proj = <$uri>) .
BIND(CONCAT(?topic, ": ", ?topicName) AS ?topicData)
}
GROUP BY ?projName
But remember that the values assigned to ?topics
will be strings, not JSON arrays:
result: [
projName: "My Project"
topics: "TOPIC1_URI: First Topic, TOPIC2_URI: Second Topic"
]
Clearly you can choose other separators than ": "
and ", "
.