SERVICE in a request

Everyone,

I'm working with the "Service" keyword. It was working well but in a new request, I do the following (formatted) :

SELECT * WHERE {
 ?object myPrefix:name ?name .
 SERVICE <http://dbpedia.org/sparql> {
      ?auto rdf:type dbo:Automobile ;
            rdfs:label ?name .
    }
}

and it sends me "INTERNAL SERVER ERROR". Please see the log screenshot.

It comes when I add ?name in the SERVICE. If I put a String, it works. But when I put any variables of my "local" request, It doesn't work.

Maybe I'm doing it wrong ?

Clément

EDIT :slight_smile:

Here's the full example i'm using :

PREFIX vco:<http://www.myOntology.eu/VCO#>
PREFIX dbo:<http://dbpedia.org/ontology/>

SELECT ?client ?marque ?serie ?modele ?taille  WHERE {
  ?infoGlobaleVehicule a vco:InfoGlobaleVehicule ;
               vco:aPourDistanceTotale ?distanceTotale;
               vco:aPourVehicule ?vehicule.
  ?infoMarqueVehicule a vco:InfoMarqueVehicule ;
                      vco:aPourMarque ?marque ;
                      vco:aPourSerie ?serie ;
                      vco:aPourModele ?modele ;
                      vco:aPourVehicule ?vehicule .           
  ?vehicule a vco:Vehicule;
            vco:aPourClient ?client. 
  ?client a vco:ClientCible ;
          vco:aPourAge ?age;
          vco:aPourEtatCivil ?etatCivil;
          vco:aPourNombreEnfants ?nombreEnfants.
  BIND (CONCAT(?marque," ",?serie) as ?marqueSerie)
  SERVICE <https://dbpedia.org/sparql> {
      ?auto rdf:type dbo:Automobile ;
            rdfs:label ?label ;
            dbo:width ?taille .
    FILTER (regex(ucase(?label),?marqueSerie))
    }
}

As you can see, i'm using ?marqueSerie on the "global" request and once again with the filter on the "Service". If I replace FILTER (regex(ucase(?label),?marqueSerie)) by FILTER (regex(ucase(?label),"anythingElse")) it works... And I don't know why :cry:

Hi Clément,

I would encourage you to first consider what you’re doing in this query. According to the bottom up evaluation semantics of SPARQL, the service query result will be joined with the local query result. How do you expect the ?marqueSerie variable to be bound in the remote query?

Jess

Hi Jess,

?marqueSerie looks like “PEUGEOT 206”. On DBpedia, It looks like “Peugeot 206”, which is not exatcly the same.

I think my query is “ok”. For the example, more than 80% can be deleted but it’s not my goal.

What I want is to match the cars of DBpedia matching the name of ?marqueSerie (who are in uppercase).

Clément

Can you share the query plan?

The query plan ? If you mean “what I want to do” (I don’t have a perfect english…) :

SELECT ?vehicle WHERE {
 ?info a vco:InfoMarqueVehicule ;
                      vco:aPourMarque ?brand;
                      vco:aPourSerie ?serie ;
                      vco:aPourVehicule ?vehicle .
 BIND (CONCAT(?brand," ",?serie) as ?brandSerie)
}

and then, I have all the vehicles of my database, with their ?brandSerie names. Then, I want to match those ?brandSeries names with DBPedia, to match something else (like their width, related cars, …)

Can you run stardog query explain on this query?

Sending me errors of “EOF” … Problems of setting this request to a one-line request !

Here we go :slight_smile:
The error :
Capture1

And the query explain :

I forgot to say something : I'm using inference.

The problem is that there are no bindings for ?marqueSerie in the body of your service query. The remote query must return results in order to join with the local query results. One option is to move the filter outside of the service block.

Jess

With Stardog 5.2.2 you might wish to try joining with a shared binding and not a filter. You would replace the FILTER in your query with bind(ucase(?label) as ?marqueSerie). The ?marqueSerie variable should take the same values locally and remotely and join properly. Stardog 5.2.2 has a new optimization to make this efficient with service queries.

Jess

That’s awesome. So is that what “Optimize execution of SERVICE clauses ” in the release notes is? Any hints on what it’s doing? That could change a lot about how you employ service queries.

Yes, I’m referring specifically to that entry. We use local statistics to determine if the local query is likely more selective than the service query. In this case we evaluate the local part of the query and perform the join by binding the variables before calling the remote service. The simplest example would be a query like this:

select * {
  values ?s { <iri1> <iri2> }
  service <...> { ?s ?p ?o }
}

Without the optimization we would have to retrieve all results from the service query and join to the local query which is a set two values. The optimization allows us to pass the bindings to the service query and only retrieve the triples associated with the two IRIs. This optimization covers arbitrary local queries which are joined with services (ie it’s not limited to VALUES). Feel free to let us know how it works or if you have some further questions.

Jess

Thanks for the information. It’s actually very helpful to know when deciding if service queries are an option. It might be a small change to it’s a big change in the viability of service queries. Since you can’t get reliable statistics on the remote endpoint am I correct in guessing that you just make a sensible guess and send bindings if they’re less than say 1k?

It’s a bit more vague, but that’s the general idea. We assume the service query returns a fairly large number of results. This should maintain the correct balance of using the optimization when it significantly reduces the size of the service query result. The other situation is that the local query returns many results and evaluating the service query first is more efficient. We’re planning on collecting some remote statistics as we already do for virtual graph as well as adding some hints to selectively enable/disable this optimization as needed.

Jess

Thanks for your answers.

Indeed, It works if I put the FILTER outside the SERVICE, but it's taking a while, and that's surely not what I want.

For the other idea, it doesn't work for me. I understood what and how it works, but It doesn't work on my side :(.

If I do the following :

SELECT ?thing WHERE {
   SERVICE <http://dbpedia.org/sparql> {
     ?thing rdf:type dbo:Automobile;
            rdfs:label ?label
     BIND(ucase(?label) as ?marqueSerie)
     }
?infoMarqueVehicule a vco:InfoMarqueVehicule ;
                    vco:aPourMarque ?marque ;
                    vco:aPourSerie ?serie ;
 BIND (CONCAT(?marque,' ',?serie) as ?marqueSerie)
} 

It sends me :
Error!

{"message":"BIND: Variable used when already in-scope: marqueSerie in expression CONCAT(?marque, \" \", ?serie)","code":"MalformedQuery"}

And then, If I do the following (which is exactly the same with the local request on first) :

SELECT ?thing WHERE {
?infoMarqueVehicule a vco:InfoMarqueVehicule ;
                    vco:aPourMarque ?marque ;
                    vco:aPourSerie ?serie ;
 BIND (CONCAT(?marque,' ',?serie) as ?marqueSerie)
      SERVICE <http://dbpedia.org/sparql> {
         ?thing rdf:type dbo:Automobile;
                rdfs:label ?label
         BIND(ucase(?label) as ?marqueSerie)
       }
} 

It sends me :Internal Server Error, and more exatcly :


which is, I think, the same error as the first above.

I'm using Stardog 5.2.2.

Thanks, Clément

Hi Clément,

The last one should work and looks like a bug. Do you have access to the Stardog home directory on the server? If so, can you send us stardog.log file to help reproduce the issue?

Thanks,
Pavel

Sure. You can find it here :
stardog.log (14.1 KB)

Thanks,
Clément

OK, thanks. This shows that the DBpedia endpoint returns 409 for your service query. I’m not exactly sure why but it might have something to do with how it handles BIND patterns.

Could you try this:

SELECT ?thing WHERE {
?infoMarqueVehicule a vco:InfoMarqueVehicule ;
                    vco:aPourMarque ?marque ;
                    vco:aPourSerie ?serie ;
 BIND (UCASE(CONCAT(?marque,' ',?serie)) as ?marqueSerie)
      SERVICE <http://dbpedia.org/sparql> {
         ?thing rdf:type dbo:Automobile;
                rdfs:label ?marqueSerie
       }
} 

I understand it probably won’t produce all results you want (because upper casing now happens outside of DBPedia, but let’s see if it at least executes.

Cheers,
Pavel

Pavel,

It does not work either. As mentioned by Jess (but it's not the exactly same case),

The problem is that there are no bindings for ?marqueSerie in the body of your service query. The remote query must return results in order to join with the local query results. One option is to move the filter outside of the service block.

So here again, it's sending me an Internal Server Error. The log file : stardog.log (14.1 KB)

Moreover and as you said, it's not doing what I really want, but I think you made me done that to test something :slight_smile:

No, ?marqueSerie is perfectly bound in this case and Stardog pushes bindings for that variable from outside of SERVICE. I don’t know why DBPedia refuses to serve this query, maybe you can find out under what circumstances their endpoint returns 409?

Cheers,
Pavel