Search code examples
sparql

Sparql - Count of multiple categories of connected nodes


In my graph, a node of category 'File' 'Owns' many nodes of varying categories. I'm trying to get a list of Files, including a count of connected nodes of specific categories.

My current best query looks like this:

SELECT ?uuid ?fileName ?tableCount ?toCount
WHERE {
    ?uuid 'Category' 'File' .
    ?uuid 'Name' ?fileName .
    {
        SELECT (COUNT(*) as ?tableCount)
        WHERE
        {
            VALUES (?category ) { ('BaseTable') }
            ?uuid 'Owns' ?elemUUID .
            ?elemUUID 'Category' ?category .
        }   
    }
    {
        SELECT (COUNT(*) as ?toCount)
        WHERE
        {
            VALUES (?category ) { ('TableOccurrence') }
            ?uuid 'Owns' ?elemUUID .
            ?elemUUID 'Category' ?category .
        }   
    }
}

The output is a distinct list of files, but the counts are the count for that category across ALL files (i.e. every file shares the same value for ?toCount, and every file shares the same value for ?tableCount).

There's obviously something I'm not understanding about the way subqueries work. Any assistance would be greatly appreciated.


Solution

  • Variables in inner queries are not scoped outside, unless they appear in the selection. What you should do is a query like this instead (forgive my editing, but this will make it much easier to follow for other users too):

    SELECT ?uuid ?fileName ?tableCount ?toCount
    WHERE {
        ?uuid :category 'File' .
        ?uuid :name ?fileName .
        {
            SELECT ?uuid (COUNT(*) as ?tableCount)
            WHERE
            {
                VALUES (?category ) { ('BaseTable') }
                ?uuid :owns ?elemUUID .
                ?elemUUID :category ?category .
            }
            GROUP BY ?uuid   #This is the missing link
        }
        {
            SELECT ?uuid (COUNT(*) as ?toCount)
            WHERE
            {
                VALUES (?category ) { ('TableOccurrence') }
                ?uuid :owns ?elemUUID .
                ?elemUUID :category ?category .
            } 
            GROUP BY ?uuid  #and here again
        }
    }