Avoid specifying number of explicitly enumerated resources?

44 Views Asked by At

I'm having trouble with my SPARQL query. I would like to have the recipes that contains fewer than the the number of ingredients I'm providing. This is the query:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rec:<http://www.receta.org#>
select ?recipe  (count(distinct ?Ingrediente) as ?oi) {
  ?recipe rec:Ingrediente ?Ingrediente
  filter not exists {
    ?recipe rec:Ingrediente ?other_ingredient
    filter( ?other_ingredient not in (rec:Cebolla,rec:Tomate, rec:Aceite, rec:Sal) )
  }}
group by ?recipe
having(  (count(distinct ?Ingrediente)) < 4)
order by (count(distinct ?Ingrediente))

Here is an example. Let's say I have these recipes:

  • prueba3: cebolla
  • prueba: cebolla, aceite
  • prueba2: cebolla, aceite, tomate
  • prueba4: cebolla, tomate, aceite, sal

Then I would like to print:

  • prueba3: cebolla
  • prueba: cebolla, aceite
  • prueba2: cebolla, aceite, tomate

I don't want to print the prueba4, because it has exactly the same amount of ingredients.

The main problem with the query is the "having" line: having((count(distinct ?Ingrediente)) < 4). In this case this works, but I don't want to put 4, I want to do it in a generic way, so I dont have to change that number every time I add more ingredients.

So any ideas of how can I change that line? Thanks!

1

There are 1 best solutions below

0
On

The 'having' clause is executed after the SELECT bindings, so you could have something like the following:

PREFIX ...
select ?recipe  (count(distinct ?Ingrediente) as ?oi) (4 AS ?count)
WHERE {
   ?recipe rec:Ingrediente ?Ingrediente
   filter not exists {
   ?recipe rec:Ingrediente ?other_ingredient
   filter( ?other_ingredient not in (rec:Cebolla,rec:Tomate, rec:Aceite, rec:Sal) )
 }}
group by ?recipe
having(?oi < ?count)
order by ?oi

...where ?count could be computed from a value queried from the data or a count of some triple matches.