It is possible to use aggregate function when inse

2019-03-01 13:17发布

问题:

I have the following query which aims to prevent the insertion in a named graph when the amount of triples is of a given number, e.g., 5.

I tried to reproduce the example showed here where the insertion of data is possible but I need to use the same named graph and, most important an aggregate function, i.e., COUNT.

INSERT 
  { 
    GRAPH <http://example/g1> { ?s ?p ?o } 
  }
WHERE
  { 
  GRAPH  <http://example/g1>
   { 
    ?s ?p ?o .
    FILTER ( COUNT(?p) < 5)
   } 
}  

Jena Fuseki raises the following error:

 Aggregate expression not legal at this point

回答1:

Yes, this is possible:

INSERT 
  { 
    GRAPH <http://example/g2> { ?s ?p ?o } 
  }
WHERE
{ 
  GRAPH <http://example/g1> {
    ?s ?p ?o .           # select all triples
    { SELECT ?s          # do a check for the selected subject
      WHERE { GRAPH <http://example/g1> { ?s ?p ?o } }
      GROUP BY ?s            # count properties per subject
      HAVING (COUNT(?p) < 5) # only subjects with less than 5 properties 
    }
  }
}

First of all, aggregate operators cannot be placed inside a FILTER clause, to use them as a conditional you have to put them in a HAVING clause instead.

Furthermore since you want to count properties per subject, you have to use GROUP BY ?s and use a subselect (which checks the restriction on the number of properties for a subject) combined with a simple pattern match.

EDIT Note that I slightly modified your original update: it's inserting into a different named graph from the one that you are querying. Inserting into the same named graph will of course work, but the results will not be observable (as you are just inserting the same data that was already present in that graph).