Комбинирайте множество набори от редове в SPARQL

Не мога да опиша проблема си официално поради лошия ми английски; нека го кажа с пример. Таблицата по-долу всъщност е групирана по „субект“, „предикат“.

Ние дефинираме набор от редове, ако те са един и същ „предмет“. Сега искам да комбинирам произволни два набора, ако те съдържат едни и същи „предикати“, да сумирам „броя“ на същия „предикат“ и да преброя броя на отделните субекти, които имат един и същи набор.

subject    predicate    count
-----------------------------
s1           p1           1
s1           p2           2
s2           p1           3
s3           p1           2
s3           p2           2

Следователно това, което се иска от тази таблица, са два комплекта:

{2, (p1, 3), (p2, 4)}, 
{1, (p1,3)} 

където в първия набор 2 показва, че има два субекта (s1 и s3), притежаващи този набор; (p1,3) е сумата от (s1, p1, 1) и (s3, p1, 2).

И така, как мога да извлека тези набори и да ги съхраня в Java?

  • Как мога да го направя с помощта на SPARQL?

  • Или първо съхранете тези тройки в Java, след това как мога да получа тези набори с помощта на Java?


Едно решение може да бъде concat предикати и брои,

SELECT (COUNT(?s) AS ?distinct)
?propset
(group_concat(?count; separator = \"\\t\") AS ?counts)
{
    SELECT ?s 
    (group_concat(?p; separator = \" \") AS ?propset)
    (group_concat(?c; separator = \" \") AS ?count
    {
        ?s ?p ?c        
    } GROUP BY ?s ORDER BY ?s
} GROUP BY ?propset ORDER BY ?propset

След това преброяването може да се отдели, след което да се сумира. Работи добре с малък набор от данни, но отнема много време.

Мисля, че ще се откажа от този странен проблем. Благодаря много за отговора.


person bobharris    schedule 14.06.2012    source източник


Отговори (1)


Да започнем с

select ?predicate (sum(?count) as ?totalcount) 
{
    ?subject ?predicate ?count
}
group by ?predicate

Това е основният бит, но групирането не е правилно (сега е изяснено).

Групиращата променлива трябва да бъде така (надявам се, че това е правилният синтаксис):

select ?subject (group_concat(distinct ?p ; separator = ",") AS ?propset)
{
    ?subject ?p ?c
}
group by ?subject

Надявам се, че това дава:

subject    propset
------------------
s1          "p1,p2" 
s2          "p1"  
s3          "p1,p2"  

Така че крайната заявка трябва да бъде:

select ?predicate (sum(?count) as ?totalcount) 
{
    ?subject ?predicate ?count .
    {
        select ?subject (group_concat(distinct ?p ; separator = ",") AS ?propset)
        {
            ?subject ?p ?c
        }
        group by ?subject
    }
}
group by ?propset ?predicate

това работи ли

person user205512    schedule 14.06.2012
comment
да, имам предвид "s1 и s3 имат един и същ комплект". съжалявам за правописната грешка, модифицирах го (и промених предикатната стойност на s2, за да стане по-ясно). Резултатът, който искам обаче, е „наборът от набори“. Два набора, да речем {p1,p2} и {p1}, не могат да се комбинират, тъй като са различни. Следователно не бихме само сумирали стойността на всеки един и същи предикат. Благодаря ви за отговора :) - person bobharris; 14.06.2012
comment
А, разбрах. Това може да е трудно, но добавих второ преминаване. - person user205512; 14.06.2012
comment
Почти е близо до това, което искам :), но продължава да работи и изглежда, че няма да даде никакъв резултат. Освен това, ако тази заявка е успешна, как мога да извлека тези набори от получената таблица? Виждам само, че получената таблица съдържа две колони, но не дава информация за наборите. За резултатите, те ще бъдат съхранени в java, така че...всъщност аз просто искам тези резултати. Благодаря ви отново. - person bobharris; 14.06.2012
comment
Ако искате комплектите, просто добавете ?propset към избраното. - person user205512; 15.06.2012
comment
Но totalcount не работи. От вашата следа, аз също използвам concat в колона 'count' и count 'subject', когато групирам по propset. След това мога да отделя броя на concat. Работи добре с малък набор от данни, но наистина е катастрофа за големи. - person bobharris; 15.06.2012
comment
О, да, предполагам, че това ще бъде сериозно бавно при големи набори от данни. Правите две пълни сканирания на данните: едното, за да разберете как са разделени данните, второто, за да направите преброяването. Не виждам начин да се избегне това. Въпреки това можете да изчислите предварително разделящия бит? - person user205512; 15.06.2012
comment
Първата таблица вече е изчислена; Опитах се да изчисля предварително тази таблица, след което използвах Jena ARQ, за да конструирам нов RDF модел, след което да го съхраня с помощта на TDB. Но все пак конструирането е непоносимо, вероятно поради ResultSet в Jena - той извлича резултата динамично.. Реших да се откажа. Благодаря ти много... - person bobharris; 15.06.2012