ThomasBKN
ThomasBKN

Reputation: 11

SPARQL multi graph request and sort (Virtuoso 7)

Is it possible to easily make a CONSTRUCT request where I would be able to check data in different graphs AND sort them by "graph preference"?

Let's say I sell products. For each product, I may have different suppliers, so that my setup would look like this:

<http://data.experiment.com/product/1> <http://purl.org/goodrelations/v1#hasCurrencyValue> "10" <http://data.experiment.com/graph/supplier/1> .
<http://data.experiment.com/product/1> <http://purl.org/goodrelations/v1#hasCurrencyValue> "8" <http://data.experiment.com/graph/supplier/2> .
<http://data.experiment.com/product/2> <http://purl.org/goodrelations/v1#hasCurrencyValue> "5" <http://data.experiment.com/graph/supplier/2> .

For each product specification, I want it from <http://data.experiment.com/graph/supplier/1>, then from <http://data.experiment.com/graph/supplier/2> if not found in <http://data.experiment.com/graph/supplier/1>.

This is what I've come up to:

CONSTRUCT 
{ 
    <http://data.experiment.com/product/1> ?p ?o .
} 
WHERE 
{ 
    GRAPH <http://data.experiment.com/graph/supplier/1> 
    { 
        OPTIONAL 
        { 
            <http://data.experiment.com/product/1> ?p1 ?o1 . 
        }
    }
    GRAPH <http://data.experiment.com/graph/supplier/2> 
    { 
        OPTIONAL 
        { 
            <http://data.experiment.com/product/1> ?p2 ?o2 . 
        }
    }
    BIND (IF (BOUND(?p1), ?p1, IF (BOUND(?p2), ?p2, UNDEF)) AS ?p)
    BIND (IF (BOUND(?o1), ?o1, IF (BOUND(?o2), ?o2, UNDEF)) AS ?o)
}

It does work pretty nice if I know what I'm looking for. Now if I consider:

CONSTRUCT 
{ 
    <http://data.experiment.com/product/1> ?p ?o . ?o ?cp ?co
} 
WHERE 
{ 
    GRAPH <http://data.experiment.com/graph/supplier/1> 
    { 
        OPTIONAL 
        { 
            <http://data.experiment.com/product/1> ?p1 ?o1 .
            OPTIONAL { ?o1 ?cp1 ?co1 . }  
        }
    }
    GRAPH <http://data.experiment.com/graph/supplier/2> 
    { 
        OPTIONAL 
        { 
            <http://data.experiment.com/product/1> ?p2 ?o2 . 
            OPTIONAL { ?o2 ?cp2 ?co2 . } 
        }
    }
    BIND (IF (BOUND(?p1), ?p1,IF (BOUND(?p2), ?p2, UNDEF)) AS ?p)
    BIND (IF (BOUND(?o1), ?o1,IF (BOUND(?o2), ?o2, UNDEF)) AS ?o)
    BIND (IF (BOUND(?cp1), ?cp1,IF (BOUND(?cp2), ?cp2, UNDEF)) AS ?cp)
    BIND (IF (BOUND(?co1), ?co1,IF (BOUND(?co2), ?co2, UNDEF)) AS ?co)
}

Sometimes it doesn't work because I explicitly BIND ?o, and ?o may not be an Object —

Virtuoso RDF01 Error Bad variable value in CONSTRUCT: "1532610063" (tag 189 box flags 0) is not a valid subject, only object of a triple can be a literal

I don't seem to find anyone trying to sort data by "graphs" and I'm struggling trying to find an "easy" way to do it. I've tried with SELECT and FROM NAMED, but you've still to manually select data from the graph you want.

If anyone can help, it is more than welcome.

Thank you.

Upvotes: 1

Views: 118

Answers (1)

ThomasBKN
ThomasBKN

Reputation: 11

Update from my previous post. Each suppliers for a given Book are stored in a "default" graph.

# Named graph : http://data.books.com/default
@prefix book: <http://data.books.com/resource/Book/>
@prefix ns: <http://data.books.com/ns#>

book:8780953608758 ns:hasSupplier <http://data.books.com/supplier/Alpha> .
book:8780953608758 ns:hasSupplier <http://data.books.com/supplier/Beta> .


# Named graph : http://data.books.com/supplier/Alpha
@prefix book: <http://data.books.com/resource/Book/>
@prefix price: <http://data.books.com/resource/Price/>
@prefix gr: <http://purl.org/goodrelations/v1#>
@prefix dc: <http://purl.org/dc/terms/>

book:8780953608758 gr:hasPriceSpecification price:8780953608758_FR_EUR .
price:8780953608758_FR_EUR gr:hasCurrencyValue "10" .
book:8780953608758 dc:available 1447632000 .

# Named graph : http://data.books.com/supplier/Beta
@prefix book: <http://data.books.com/resource/Book/>
@prefix price: <http://data.books.com/resource/Price/>
@prefix gr: <http://purl.org/goodrelations/v1#>
@prefix dc: <http://purl.org/dc/terms/>

book:8780953608758 gr:hasPriceSpecification price:8780953608758_FR_USD .
price:8780953608758_FR_USD gr:hasCurrencyValue "8" .
book:8780953608758 dc:available 1547632000 .

The first subquery in the query bellow use the graph http://data.books.com/default to find and sort all our suppliers graphs for the book 8780953608758. It then matches another pattern against that graph.

PREFIX book: <http://data.bookeen.com/resource/Book/>

CONSTRUCT 
{
    book:8780953608758 ?p ?o . ?o ?cp ?co .
}
WHERE 
{
    {
        SELECT ?supplier 
        FROM <http://data.books.com/default>
        WHERE 
        {
            VALUES (?supplier ?priority) 
            { 
                (<http://data.books.com/supplier/Beta> 1) 
                (<http://data.books.com/supplier/Alpha> 2)   
            }
            book:8780953608758 <http://data.books.com/ns/hasSupplier> ?supplier.
        }
        ORDER BY ?priority
        LIMIT 1
    }

    GRAPH ?supplier
    {
        book:8780953608758 ?p ?o .
        OPTIONAL { ?o ?cp ?co . }
    }
}

Upvotes: 0

Related Questions