On 11/12/15 12:07, Osma Suominen wrote:
Hi Andy!

On 11/12/15 13:54, Andy Seaborne wrote:
On 10/12/15 20:18, Osma Suominen wrote:
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX text: <http://jena.apache.org/text#>

SELECT *
WHERE {
   GRAPH <http://www.yso.fi/onto/yso/> {
     GRAPH <urn:x-arq:UnionGraph>  {
       (?s ?score ?literal) text:query 'musiikkikasv*' .
     }
     ?s skos:prefLabel ?label .
     FILTER (LANG(?label)=LANG(?literal))
   }
}

You are running with union default graph? In which case that's good.

Yes, I'm using unionDefaultGraph=true.

Else use <urn:x-arq:DefaultGraph>

Right.

One of my regrets in SPARQL is that you can't get back to the default
graph inside a GRAPH block.

Exactly. That's the problem here, and the workaround requires using
these magic ARQ graph names. Or...

The key to your query is the back that the FILTER covers the inner GRAPH.

This should work:

WHERE {
    (?s ?score ?literal) text:query 'musiikkikasv*' .
    GRAPH <http://www.yso.fi/onto/yso/> { ?s skos:prefLabel ?label . }
    FILTER (LANG(?label)=LANG(?literal))
}

and it gets optimized into a

...something missing from your sentence?

gets optimized into a stream execution.


Indeed, this works. It's also faster than I expected (20ms). It appears
that when the expression within the GRAPH block gets executed, ?s is
already bound to a single resource (as returned by text:query).
Otherwise the { ?s skos:prefLabel ?label } pattern would have to iterate
over many potential solutions, which would have taken more time.

which is why it hits the GRAPH with ?s bound.

What the optimizer has done is notice that the bottom up execution (the correct form) has the same output as streaming. That FILTER inside the GRAPH would block that because streaming changes variable scope - the ?literal in this case.

In the algebra from qoarse look for "sequence" (joins does index join, global scope variables) and "conditional" (same, expect leftjoins).


You had an OPTIONAL in the original:

WHERE {
     (?s ?score ?literal) text:query 'musiikkikasv*' .
     OPTIONAL {
         GRAPH <http://www.yso.fi/onto/yso/>
         { ?s skos:prefLabel ?label . }
     }
     FILTER (!BOUND(?label) || LANG(?label)=LANG(?literal))
}

or

WHERE {
(?s ?score ?literal) text:query 'musiikkikasv*' .
    OPTIONAL {
      GRAPH <http://www.yso.fi/onto/yso/>
       { ?s skos:prefLabel ?label . }
      FILTER (LANG(?label)=LANG(?literal))
    }
}

In this one it is very important the FILTER is at the top level of the
OPTIONAL{} block.  It puts ?literal in-scope because the FILTER is part
of the LeftJoin condition.

I see - moving the FILTER is indeed the key. I don't quite understand
all the magic that's happening here, but I think I can use this to get a
working solution.

Thanks a lot for all the explanations and help!

Glad to help,

We still have that weird "graph" getting redefined which is most odd.

Back to the release ...

You retracted your -1 ... if you have time (and we're all short of that!), could say what your vote is now with a [VOTE] message.

        Andy


-Osma



Reply via email to