2016-06-08 3 views
0

В семантическом веб-графе у меня есть набор объектов (S1, S2, ..., Sn) и набор предикатов (P1, P2, ..., Pn). Я хочу группировать экземпляры на основе их предикатов (т. Е. Выбирать все экземпляры, которые имеют одинаковый набор предикатов, независимо от значения объекта).SPARQL: групповые объекты на основе предикатов

Например, если у меня есть

S1 P1 v1. 
S1 P2 v2. 
S2 P3 v3. 
S2 P4 v4. 
S3 P1 v5. 
S3 P2 v6. 

Я бы ожидать, чтобы иметь две группы {S1, S3} и {S2}. Я сам создаю график, поэтому я могу изменить его структуру, если это поможет достичь этого требования.

ответ

2

Это немного сложнее, чем могло бы звучать, и я не совсем уверен, возможно ли это полностью, но я думаю, что вы можете достичь этого в большинстве конечных точек. Если вы хотите группировать на основе набор предикатов, которые есть у субъекта, тогда вам сначала нужно будет получить предикатов, которые есть у субъекта, и таким образом, который можно сравнить с другими наборами предикаты. SPARQL не имеет никакого понятия о наборе значений типа данных, но с использованием GROUP_CONCAT и отчетливого, вы можете получить строку, содержащую все некоторые предикатов, и если вы используете заказ при их выборе, большинство конечных точек будут держать заказ неповрежденными, так что строки группы group_concat являются по существу каноническими. Однако это поведение, насколько я могу судить, не гарантировано спецификацией.

@prefix : <urn:ex:> 

:S1 :P1 :v1 . 
:S1 :P2 :v2 . 
:S2 :P3 :v3 . 
:S2 :P4 :v4 . 
:S3 :P1 :v5 . 
:S3 :P2 :v6 . 
prefix : <urn:ex:> 

#-- The behavior in most (all?) endpoints seems to be 
#-- to preserve the order during the group_concat 
#-- operation, so you'll get "noramlized" values 
#-- for ?preds. I don't think is *guaranteed*, though. 
select ?s (group_concat(?p) as ?preds) where { 
    #-- get the values of ?s and ?p and ensure that 
    #-- they're in some kind of standarized order. 
    #-- Just ordering by ?p might be fine, too. 
    { select distinct ?s ?p { 
     ?s ?p ?o 
    } 
    order by ?p 
    } 
} 
group by ?s 
------------------------------- 
| s | preds     | 
=============================== 
| :S2 | "urn:ex:P3 urn:ex:P4" | 
| :S3 | "urn:ex:P1 urn:ex:P2" | 
| :S1 | "urn:ex:P1 urn:ex:P2" | 
------------------------------- 

Теперь вам просто нужно сделать еще один шаг дальше и группировать эти результаты по Preds:

prefix : <urn:ex:> 

select (group_concat(?s) as ?subjects) { 
    select ?s (group_concat(?p) as ?preds) where { 
    { select distinct ?s ?p { 
     ?s ?p ?o 
     } 
     order by ?p 
    } 
    } 
    group by ?s 
} 
group by ?preds 
------------------------- 
| subjects    | 
========================= 
| "urn:ex:S1 urn:ex:S3" | 
| "urn:ex:S2"   | 
------------------------- 
+0

Ого, вы удивительный !. Я думал о создании хэш-кода для каждого экземпляра на основе его предиката. Но ваше решение более эффективно, и оно работает с Йеной Фусеки. –