2012-11-15 2 views
3

J'ai un magasin triple qui contient des données d'archive de courrier. Alors disons que j'ai beaucoup de personnes (foaf:Person) qui ont envoyé (ex:hasSent) et reçu (ex:hasReceived) des emails (ex:Email).Plusieurs agrégats dans SPARQL

Exemple:

SELECT ?person ?email 
WHERE { 
    ?email rdf:type ex:Email. 
    ?person rdf:type foaf:Person; 
      ex:hasSent ?email. 
} 

Les mêmes œuvres pour ex:hasReceived, bien sûr. Maintenant, j'aimerais faire des statistiques et des analyses, c'est-à-dire déterminer combien de courriels un individu a envoyé et reçu. Faire cela pour un seul prédicat est une simple agrégation:

SELECT ?person (COUNT(?email) AS ?count) 
WHERE { 
    ?email rdf:type ex:Email. 
    ?person rdf:type foaf:Person; 
      ex:hasSent ?email. 
} 
GROUP BY ?person 

Cependant, j'ai besoin besoin le nombre de courriels reçus ainsi et je voudrais le faire sans avoir à émettre une requête distincte. J'ai donc essayé les éléments suivants:

SELECT ?person (COUNT(?email1) AS ?sent_emails) (COUNT(?email2) AS ?received_emails) 
WHERE { 
    ?person rdf:type foaf:Person. 

    ?sent_email rdf:type ex:Email. 
    ?person ex:hasSent ?sent_email. 

    ?received_email rdf:type ex:Email. 
    ?person ex:hasReceived ?received_email. 
} 
GROUP BY ?person 

Cela ne semble pas avoir raison, comme les numéros pour les e-mails envoyés par rapport reçus étaient exactement les mêmes. Je suppose que c'est parce que ma déclaration SPARQL résulte d'un produit croisé de tous les mails qu'une personne a jamais envoyé et reçu, non?

Que dois-je faire pour que les statistiques soient correctes au cas par cas?

Répondre

1

COUNT(?email1) est sans compter que ?email1 est indéfini. En outre, il existe un produit croisé partiel que vous mentionnez - DISTINCT aidera.

Essayez (COUNT(DISTINCT ?sent_email) AS ?sent_emails)

+0

Vous avez raison, '? Email1' était non liée. J'avais poli la requête pour SO, mais pas complètement. – cyroxx