2016-10-13 3 views
2

Вот мой запрос:SPARQL рассчитывать не существующие свойства, как нулевой

PREFIX  : <http://example.org/ns#> 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
SELECT ?id ?name (count(?s) as ?count) 
WHERE { 
    ?t a  :Tag ; 
     :hasId ?id ; 
     :hasName ?name 
    OPTIONAL { ?s :hasTag ?t ; 
       rdf:type ?type } 
    FILTER (?type in (:Client, :Project, :Staff)) 
} GROUP BY ?id ?name 

Теги без каких-либо объектов, которые не включены в результат. Как я могу получить их, не используя союз? Эффективность также важна.

Целью является сбор информации о тегах (id, name) и количестве объектов, которые они назначают (если таких объектов не должно быть 0). Пример данных тегов:

:tag912 :hasId  "912"^^xsd:integer 
:tag912 :hasName  "Phones" 

Этот тег относится к 6 объектам.

Этот запрос работает для меня:

PREFIX :  <http://example.org/ns#> 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
SELECT ?id ?name ?count 
WHERE { 
    { 
    SELECT ?id ?name (count(?s) as ?count) 
    WHERE { 
     ?t a  :Tag ; 
      :hasId ?id ; 
      :hasName ?name . 
     ?s :hasTag ?t ; 
      rdf:type ?type 
     FILTER (?type in (:Client, :Project, :Staff)) 
    } GROUP BY ?id ?name 
    } UNION { 
    SELECT ?id ?name (0 as ?count) 
    WHERE { 
     ?t a  :Tag ; 
     :hasId ?id ; 
     :hasName ?name 
     FILTER not exists { ?s :hasTag ?t } 
    } 
    } 
} 

Как я могу использовать привязок здесь? Улучшит ли производительность? Спасибо

+0

Было бы неплохо, если бы вы предоставили дополнительную информацию, среди прочего, цель запроса, образцы данных и т. Д. – AKSW

+1

И вы хотите иметь количество объектов, у которых нет тега? Вы знаете, как получить только количество тегов, у которых нет тега? С вашим запросом я не вижу способа избежать объединения или подвыборки, поскольку вы группируете по тегу Id и имени тега, так что должно быть id или. имя, которое обозначает немаркированные объекты? BIND + IF-ELSE может быть возможностью привязать тег «немаркированный» к тем объектам, у которых нет тега – AKSW

+0

Спасибо за ответ, я добавил более подробную информацию к вопросу. Как я могу использовать BIND + IF-ELSE здесь? Поскольку я думаю, что это должно быть быстрее, чем объединение – anku

ответ

1

Почему не использование UNION?

Помимо этого, ваш запрос ориентирован на ?t тегов и их ?id и ?name - так что это не удивительно, что результаты не включают ?s объекты, которые испытывают недостаток в ?t и, следовательно, не хватает какой-либо ?id и ?name ...

Я думаю, это может заставить вас идти в правильном направлении -

PREFIX  : <http://example.org/ns#> 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 

SELECT ?id 
     ?name 
     (count(?s) as ?count) 
WHERE 
    {   ?s rdf:type ?type 
       FILTER (?type IN (:Client, :Project, :Staff)) . 
    OPTIONAL { ?s :hasTag ?t . 
       ?t rdf:type :Tag ; 
        :hasId ?id ; 
        :hasName ?name } 
    } 
GROUP BY ?id ?name 
+0

Благодарим вас за ответ. Но это тоже не работает для меня. Я думаю, что на самом деле это тот же запрос, что и в начале вопроса – anku

+2

. Мой запрос не совпадает с вашим оригиналом. Но обновления вашего вопроса изменили вашу заявленную цель (от «сколько объектов не имеют тега?» До «сколько объектов применяется каждый тэг?») И сделать мой измененный запрос несущественным. – TallTed

0

вы можете проверить, если s связан в фильтре:

PREFIX  : <http://example.org/ns#> 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
SELECT ?id ?name (COUNT(?s) as ?count) 
WHERE { 
    ?t a  :Tag ; 
     :hasId ?id ; 
     :hasName ?name . 
    OPTIONAL { 
    ?s :hasTag ?t ; 
      rdf:type ?type . 
    } 
    FILTER (!BOUND(?s) || ?type in (:Client, :Project, :Staff)) 
} GROUP BY ?id ?name 

Однако я не знаю, было ли это быстрее, чем объединение (или объединение союзов).

+0

У меня не так много данных, но для 1000 тегов и 20000 объектов я получаю – anku

+0

289 мс для вашего запроса – anku

+0

480 мс для моего союза – anku

Смежные вопросы