2016-04-14 3 views
3

У меня есть запрос построить в SPARQL, который полезен для получения сведений о контрактах:Как я могу построить график RDF для некоторых людей с одним CONSTRUCT?

CONSTRUCT { 
?contract dcterm:identifier ?id . 
?contract rdfs:label ?label . 

?contract pc:bidder ?bidder . 
} 
WHERE { 
    OPTIONAL { 
     ?contract dcterm:identifier ?id . 
    } 
    OPTIONAL { 
     ?contract rdfs:label ?label . 
    } 

    OPTIONAL { 
     ?contract pc:tender ?tender . 
     ?tender pc:bidder ?bidder . 
    } 
} 

У меня есть список контрактов, например ПК: c1, шт: c2, и я хотел бы получить в одном одиночный запрос (или один HTTP-запрос), данные о них обоих.

Первая идея заключается в том, чтобы заменить переменную контракта с каждым Ури и избежать конфликтов между другими переменными:

CONSTRUCT { 
    pc:c1 dcterm:identifier ?id1 . 
    pc:c1 rdfs:label ?label1 . 

    pc:c1 pc:bidder ?bidder1 . 


    pc:c2 dcterm:identifier ?id2 . 
    pc:c2 rdfs:label ?label2 . 

    pc:c2 pc:bidder ?bidder2 . 
} 
WHERE { 
    OPTIONAL { 
     pc:c1 dcterm:identifier ?id1 . 
    } 
    OPTIONAL { 
     pc:c1 rdfs:label ?label1 . 
    } 

    OPTIONAL { 
     ?pc:c1 pc:tender ?tender1 . 
     ?tender1 pc:bidder ?bidder1 . 
    } 
    OPTIONAL { 
     pc:c2 dcterm:identifier ?id2 . 
    } 
    OPTIONAL { 
     pc:c2 rdfs:label ?label2 . 
    } 

    OPTIONAL { 
     ?pc:c2 pc:tender ?tender2 . 
     ?tender2 pc:bidder ?bidder2 . 
    } 
} 

Проблема заключается в том, что со многими URIs запрос может стать довольно большим.

Есть ли более компактный способ написать его?

Я попытался с оператором IN (https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#OperatorMapping - 17.4.1.9), но Virtuoso, похоже, не анализирует запрос. Ключевое слово Alse the VALUES (https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#inline-data) показалось хорошим решением, но Йена, похоже, не разобрала его правильно.

+1

Какая версия Jena не работает? – AKSW

ответ

4

Просто используйте значения, чтобы указать значения ? Договор, который вы хотите. (Jena поддерживает значения, так что, возможно, там была опечатка в тесте?) Вот что она будет выглядеть так:

CONSTRUCT { 
    ?contract dcterm:identifier ?id . 
    ?contract rdfs:label ?label . 
    ?contract pc:bidder ?bidder . 
} 
WHERE { 
    VALUES ?contract { pc:c1 pc:c2 }   #-- this is the new line 
    OPTIONAL { 
     ?contract dcterm:identifier ?id . 
    } 
    OPTIONAL { 
     ?contract rdfs:label ?label . 
    } 

    OPTIONAL { 
     ?contract pc:tender ?tender . 
     ?tender pc:bidder ?bidder . 
    } 
} 

Для одиночных матчей собственности, вы также можете сделать это короче с значениями для свойства. Вы также можете использовать путь собственности, чтобы сократить часть участника торгов:

CONSTRUCT { 
    ?contract ?p ?o . 
    ?contract pc:bidder ?bidder . 
} 
WHERE { 
    VALUES ?contract { pc:c1 pc:c2 } 
    VALUES ?p { dcterm:identifier rdfs:label } 
    OPTIONAL { 
     ?contract ?p ?o 
    } 
    OPTIONAL { 
     ?contract pc:tender/pc:bidder ?bidder . 
    } 
} 
+0

Вы правы, ошибка заключалась в использовании разделителя между uris внутри VALUES! Очень чистый и ваш второй намек! благодаря –