The "main" names within the structure are assigend arbitrarily (e.g., "847584" and "8945); we are trying to get a binding based on the "Id" field as shown below. This works fine when pointing to a concrete key like "847584". All mapped values are included correctly. Of course, the values from the other section ("8945") are missing:
MAPPING
FROM JSON {
{
"847584": {
"PhraseId": "?id",
"Duration": "?duration",
"SentimentScore": "?sentiment"
}
}
}
TO{
?phrase a :Phrase ;
:has_sentiment ?sentiment ;
:has_duration ?duration .
} WHERE {
BIND(TEMPLATE("http://example.com/phrase/{id}") AS ?phrase)
}
Is there a way to use a placeholder for a JSON name, e.g.:
I'm not sure of any way to do it in the mapping. (maybe someone else knows of a way) but if you're able to preprocess the json files you could break them out to separate json files based on ?MY_PLACEHOLDER and map those. You could do it with jq and something like the following
for f in `cat input.json | jq -r 'keys[]'` ; do
cat input.json | jq ".$f" > $f.json
done
Your mapping looks exactly right with the exception that the names of the fields in the JSON do not match the names of the fields in your mappings (Id vs PhraseId, type isn't mapped, 847584 doesn't have a sentiment score, ABC and DEF have the same Id of 47d88f8a-30bd-4e56-b13b-758f7012e8e4).
If I touch these items up it works like I think you expect:
json $ cat placeholders.json
{
"847584":{
"Type":"ABC",
"Duration":1290.0,
"PhraseId":"47d88f8a-30bd-4e56-b13b-ABC"
},
"8945":{
"Type":"DEC",
"PhraseId":"47d88f8a-30bd-4e56-b13b-DEC",
"SentimentScore":50.0
}
}
json $ cat placeholders.sms
PREFIX : <example:>
MAPPING
FROM JSON {
{
"?MY_PLACEHOLDER":{
"Type":"?type",
"Duration":"?duration",
"PhraseId":"?id",
"SentimentScore":"?sentiment"
}
}
}
TO {
?phrase a :Phrase ;
:has_type ?type ;
:has_duration ?duration ;
:has_sentiment ?sentiment .
}
WHERE {
BIND(TEMPLATE("http://example.com/phrase/{id}") AS ?phrase)
}
json $ sa db create -n json
Successfully created database 'json'.
json $ sa virtual import json placeholders.sms placeholders.json
Import completed successfully in 00:00:00.072.
json $ s data export json
@prefix : <http://api.stardog.com/> .
@prefix stardog: <tag:stardog:api:> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
<http://example.com/phrase/47d88f8a-30bd-4e56-b13b-ABC> a <example:Phrase> ;
<example:has_duration> 1290.0 ;
<example:has_type> "ABC" .
<http://example.com/phrase/47d88f8a-30bd-4e56-b13b-DEC> a <example:Phrase> ;
<example:has_type> "DEC" ;
<example:has_sentiment> 50.0 .
json $
If it is intended that multiple objects share the same Id, then you'll get a single node of type Phrase with properties pulled from each object with mapped values.
Yes, this is exactly what is intended. Multiple objects share the same ID ("PhraseID") and contribute with various and different values (eg., duration from one object and sentiment from another one) in order to build one "Phrase" node.
It is good to know that I can acutally use a variable for a JSON-key. Currently, the import does not work however when doing so.