从 SPARQL 查询中获取值

Get value from a SPARQL query

以下查询足以让我获取食谱的名称和其中的配料量。我也想得到食谱中的成分。我如何修改我的查询来执行此操作?

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 ?r (count(distinct ?Ingrediente) as ?oi) ?i {
  ?r rec:Ingrediente ?Ingrediente
  filter not exists {
    ?r rec:Ingrediente ?other_ingredient
    filter( ?other_ingredient not in (rec:Cebolla,rec:Tomate, rec:Aceite, rec:Sal, rec:Lechuga) )
  }
}
group by ?r ?i
order by (count(distinct ?Ingrediente))

执行此操作的最简单方法当然是将要具有 ?Ingrediente 值的变量添加到 SELECT 子句中:

SELECT ?r (count(distinct ?Ingrediente) as ?oi) ?Ingrediente 

(顺便说一句,你有一个变量 ?i 似乎没有做任何事情 - 它永远不会绑定到一个值。从现在开始我将忽略该变量)

但是,由于您使用的是聚合和分组,因此还需要将变量添加到 GROUP BY 子句中:

GROUP BY ?r ?Ingrediente

这或多或少可能会起作用,但问题是您正在混合一个聚合(成分数量的计数)和该聚合的各个值。您将在结果中得到大量几乎重复的行(每个食谱的每种成分对应一个行),并且由于分组的变化,现在计数也可能是错误的。

所以 - 需要替代方法。您可以做的是使用 GROUP_CONCAT 聚合函数。这会选择所有值并将它们连接成一个(space 分隔,至少默认情况下)列表。如果您使用它,您也不必调整 GROUP BY 子句。如下:

SELECT ?r (count(distinct ?Ingrediente) as ?oi) (GROUP_CONCAT(DISTINCT ?Ingrediente) as ?List) 

结果将如下所示:

  ?r          ?oi                ?List 
  :r1           3                "rec:Tomate rec:Sal rec:Aceita" 

该列表可能包含完整的 URI 而不是前缀名称,但您明白了。当然,如果您想要成分的名称而不是它们的 URI,则需要通过匹配适当的 属性(例如 rdfs:label)来查询这些名称,然后使用 GROUP_CONCAT 属性 值。