返回满足某些条件的实体的SPARQL查询

返回满足某些条件的实体的SPARQL查询,sparql,rdf,semantic-web,Sparql,Rdf,Semantic Web,我需要编写一个SPARQL查询来返回那些满足固定数量条件的实体(并不总是全部)。我的想法是,我需要得到所有满足4个条件中的2个的实体。我正在写下面的问题 SELECT ?ent WHERE { BIND(0 as ?cnt). OPTIONAL { ?ent ns:age ?age. FILTER(?age > 20 && ?age <= 40). BIND(?cnt + 1, ?cnt). }.

我需要编写一个SPARQL查询来返回那些满足固定数量条件的实体(并不总是全部)。我的想法是,我需要得到所有满足4个条件中的2个的实体。我正在写下面的问题

SELECT ?ent WHERE {
    BIND(0 as ?cnt).
    OPTIONAL {
       ?ent ns:age ?age.
       FILTER(?age > 20 && ?age <= 40).
       BIND(?cnt + 1, ?cnt).
    }.
    OPTIONAL {
        ?ent ns:livesIn nst:Mauritius.
        BIND(?cnt + 1, ?cnt).
    }.
    OPTIONAL {
        ?ent ns:maritalStatus nst:Married.
        BIND(?cnt + 1, ?cnt).
    }.
    OPTIONAL {
        ?ent ns:fatherIs/ns:age ?fatherAge.
        FILTER(?fatherAge > 55 && ?fatherAge <= 80).
        BIND(?cnt + 1, ?cnt).
    }
} HAVING(?cnt > 2)
SELECT?entwhere{
绑定(0为?cnt)。
可选的{
?耳鼻喉科:年龄?年龄。
过滤器(?年龄>20岁和55岁和2岁)
我是否以正确的方式处理问题?我是否遗漏了什么?是否有更好的方法解决我的问题

编辑1:上面提到的查询给了我一个错误。现在我正在尝试这个

SELECT ?ent ?cnt WHERE {
    BIND(0 as ?cnt1).
    BIND(0 as ?cnt2).
    BIND(0 as ?cnt3).
    BIND(0 as ?cnt4).
    OPTIONAL {
       ?ent ns:age ?age.
       FILTER(?age > 20 && ?age <= 40).
       BIND(1 as ?cnt1).
    }.
    OPTIONAL {
        ?ent ns:livesIn nst:Mauritius.
        BIND(1 as ?cnt2).
    }.
    OPTIONAL {
        ?ent ns:maritalStatus nst:Married.
        BIND(1 as ?cnt3).
    }.
    OPTIONAL {
        ?ent ns:fatherIs/ns:age ?fatherAge.
        FILTER(?fatherAge > 55 && ?fatherAge <= 80).
        BIND(1 as ?cnt4).
    }
    BIND((?cnt1 + ?cnt2 + ?cnt3 + ?cnt4) as ?cnt)
} ORDER BY DESC(?cnt)
SELECT?ent?cnt WHERE{
绑定(0为?cnt1)。
绑定(0为?cnt2)。
绑定(0为?cnt3)。
绑定(0为?cnt4)。
可选的{
?耳鼻喉科:年龄?年龄。

过滤(?年龄>20岁和55岁和55岁和父亲年龄我建议以下天真的方法

SELECT?ent?cnt WHERE{
?ent a foaf:个人。
可选的{
?耳鼻喉科:年龄?年龄。
过滤器(?年龄>20岁和55岁和2岁)
}按描述排序(?cnt)

您最近的查询有两个问题:

  • 外部
    BIND
    s覆盖内部绑定(或者说它们之间没有连接)
  • 您将从
    可选
    开始(请参阅)

    • 我建议采用以下天真的方法

      SELECT?ent?cnt WHERE{
      ?ent a foaf:个人。
      可选的{
      ?耳鼻喉科:年龄?年龄。
      过滤器(?年龄>20岁和55岁和2岁)
      }按描述排序(?cnt)
      

      您最近的查询有两个问题:

      • 外部
        BIND
        s覆盖内部绑定(或者说它们之间没有连接)
      • 您将从
        可选
        开始(请参阅)

      可能应该详细说明我在上述评论中建议的并集用法。例如,检索与第一个条件匹配的所有内容,并至少检索其余条件中的一个,或者检索第二个条件成立的解决方案,以及其他两个条件中的至少一个或最后两个条件同时存在的解决方案,类似于:

      SELECT ?ent WHERE {
      {
          ?ent ns:age ?age.
          FILTER(?age > 20 && ?age <= 40).
          {
              ?ent ns:livesIn nst:Mauritius.
          } union {
              ?ent ns:maritalStatus nst:Married.
          } union {
                  ?ent ns:fatherIs/ns:age ?fatherAge.
                  FILTER(?fatherAge > 55 && ?fatherAge <= 80).
          }
      } union {
          ?ent ns:livesIn nst:Mauritius.
          {
              ?ent ns:maritalStatus nst:Married.
          } union {
                  ?ent ns:fatherIs/ns:age ?fatherAge.
                  FILTER(?fatherAge > 55 && ?fatherAge <= 80).
          }    
      } union {
          ?ent ns:maritalStatus nst:Married.
          ?ent ns:fatherIs/ns:age ?fatherAge.
          FILTER(?fatherAge > 55 && ?fatherAge <= 80).
        }
      }
      
      SELECT?entwhere{
      {
      ?耳鼻喉科:年龄?年龄。
      过滤器(?年龄>20岁、55岁、55岁、55岁、55岁、20岁、55岁、1岁)
      
      可能应该详细说明我在上面的评论中建议的联合用法。例如,检索与第一个条件匹配的所有内容,并且至少检索其余条件中的一个,或者检索第二个条件成立的解决方案以及其他两个条件中的至少一个,或者检索最后两个条件同时存在的解决方案,这样的话:

      SELECT ?ent WHERE {
      {
          ?ent ns:age ?age.
          FILTER(?age > 20 && ?age <= 40).
          {
              ?ent ns:livesIn nst:Mauritius.
          } union {
              ?ent ns:maritalStatus nst:Married.
          } union {
                  ?ent ns:fatherIs/ns:age ?fatherAge.
                  FILTER(?fatherAge > 55 && ?fatherAge <= 80).
          }
      } union {
          ?ent ns:livesIn nst:Mauritius.
          {
              ?ent ns:maritalStatus nst:Married.
          } union {
                  ?ent ns:fatherIs/ns:age ?fatherAge.
                  FILTER(?fatherAge > 55 && ?fatherAge <= 80).
          }    
      } union {
          ?ent ns:maritalStatus nst:Married.
          ?ent ns:fatherIs/ns:age ?fatherAge.
          FILTER(?fatherAge > 55 && ?fatherAge <= 80).
        }
      }
      
      SELECT?entwhere{
      {
      ?耳鼻喉科:年龄?年龄。
      过滤器(?年龄>20岁、55岁、55岁、55岁、55岁、20岁、55岁、1岁)
      

      给定非法的SPARQL语法,您的整个查询无法运行。您是否尝试过运行它?不,类似于
      SELECT*WHERE{BIND(0 as?cnt)。可选的{s:p?o.BIND(?cnt+1 as?cnt)}
      不起作用,因为它只是
      可选
      条款变量的左连接。您的语法错误是正确的。我已经修改了我的查询。当可选中的所有变量都未绑定时,这很棘手。如果第一个块为?ent提供了任何解决方案,则查询的其余部分将仅限于这些值,因此顺序问题。我可以建议您在任意两个条件之间使用并集。当然它会给出0。您首先声明
      ?cnt1
      ?cnt2
      ?cnt3
      、和
      ?cnt4
      等于0,然后声明
      ?cnt
      是这些零的总和。如果给定非法SPARQL synt,则整个查询不起作用你试过运行它吗?没有,类似于
      SELECT*WHERE{BIND(0as?cnt)。可选的{s:po.BIND(?cnt+1as?cnt)}
      不起作用,因为它只是
      可选
      条款变量的左连接。您的语法错误是正确的。我已经修改了我的查询。当可选中的所有变量都未绑定时,这很棘手。如果第一个块为?ent提供了任何解决方案,则查询的其余部分将仅限于这些值,因此顺序问题。我可以建议您在任意两个条件之间使用并集。当然,它会给出0。您首先声明
      ?cnt1
      ?cnt2
      ?cnt3
      ,和
      ?cnt4
      等于0,然后声明
      ?cnt
      是这些零的总和。不能保证foaf:Person在ese实体…是的,当然。但是应该存在一些东西。我会解释(但你显然知道)。你的建议很有效。但我无法将
      绑定
      转换为整数。因此我使用了if条件。类似于
      if(绑定(?年龄),1,0)
      不能保证foaf:Person在这些实体中存在……是的,当然。但是应该存在一些东西。我会解释(但你显然知道)。你的建议是有效的。但是我无法将
      绑定
      转换为整数。所以我使用了if条件。类似于
      if(绑定(?年龄),1,0)
      我不明白为什么您在第二次查询中需要
      绑定(1 as?cnt)
      。这是一个超级功能,因为您可以简单地执行
      count(*)
      来计算每个实体的三元组。是的,这是多余的。我不明白为什么您需要
      绑定(1 as?cnt)
      在您的第二个查询中。如果您只需执行
      count(*)
      即可计算每个实体的三元组,则这是一个超级功能。是的,这是多余的。