sparql检查是否存在某个属性,并将答案设为零

安娜·戴维(Ania David)

这是我的最低数据:

@prefix : <http://example.org/rs#>

:item :hasContext [:weight 0.1 ; :doNotRecommend true] , [:weight 0.2 ] .

:anotherItem :hasContext [:weight 0.4] , [ :weight 0.5 ] .

如您所见,每个对象item都有一个或多个 hasContext,其对象hasContext是一个可能具有doNotRecommed谓词的实例

我想要的是,如果这些实例之一(是hasContext的对象)包含donNotRecommed,我希望整个和为零。**和总和是指权重的总和**,因此,换句话说,如果该属性存在,则忽略所有权重(无论权重是否存在),只需将其设置为零即可

我的查询

select ?item (SUM(?finalWeight) as ?summedFinalWeight) {
 ?item :hasContext ?context .
  optional 
  {
    ?context :doNotRecommend true .
    bind( 0 as ?cutWeight) 
  }
  optional
  {
    ?context :weight ?weight .
  } 
  bind ( if(bound(?cutWeight), ?cutWeight , if(bound(?weight), ?weight, 0.1) ) as ?finalWeight )
}
group by ?item

结果

在此处输入图片说明

看一下:item的值0.2(我知道原因,这是因为0.2加零(而这个零是因为doNotRecommend在那)),但我不知道解决方案,在这种情况下,我想要的是零的:item

(提示,我知道我总是可以在此查询的更高级别上运行另一个查询并解决它,或者我可以使用不存在的过滤器来解决它,但是我希望在同一查询中解决它,因为我应该是什么最少的数据,而在我的本体中,获得权重和这些对象是一个很长的查询

更新1

这是我真正的查询,第一部分(在联合之前)检查用户是否确认上下文,第二部分(在联合之后)检查用户是否不符合上下文,在这里我要检查是否上下文具有doNotRecommendOrNot请确保两个部分一起验证是不正确的

SELECT  ?item (SUM(?finalWeightFinal) AS ?userContextWeight)
WHERE
  { VALUES ?user { bo:ania }
    ?item  rdf:type  rs:RecommendableClass
    OPTIONAL
      {   { FILTER EXISTS { ?item  rdf:type  ?itemClass }
            ?item     rdf:type           rs:RecommendableClass .
            ?userContext  rdf:type       rs:UserContext ;
                      rs:appliedOnItems  ?itemClass ;
                      rs:appliedOnUsers  ?userClass
            FILTER EXISTS { ?user  rdf:type  ?userClass }
            OPTIONAL
              { ?userContext  rs:hasWeightIfContextMatched  ?weight }
            BIND(if(bound(?weight), ?weight, 0.2) AS ?finalWeight)
          }
        UNION
          { ?item     rdf:type           rs:RecommendableClass .
            ?userContext  rdf:type       rs:UserContext ;
                      rs:appliedOnItems  ?itemClass ;
                      rs:appliedOnUsers  ?userClass
            FILTER EXISTS { ?item  rdf:type  ?itemClass }
            FILTER NOT EXISTS { ?user  rdf:type  ?userClass }
            OPTIONAL
                #Here is the skip
              { ?userContext  rs:doNotRecommendInCaseNotMatch  true
                BIND(0 AS ?skip)
              }
            OPTIONAL
              { ?userContext  rs:hasWeightIfContextDoesNotMatch  ?weight }
            BIND(if(bound(?weight), ?weight, 0.1) AS ?finalWeight)
          }
      }
    BIND(if(bound(?finalWeight), ?finalWeight, 1) AS ?finalWeightFinal)
  }
GROUP BY ?item

更新2

在获得@Joshua Taylor的赞赏答复之后,我尝试在实际案例中应用他的方法,但是这次添加了 filter !bound(?skip)

这是查询

SELECT  ?item ?itemClass ?userContext ?skip ?finalWeight 
WHERE
  { #{ 
    in this block i just select the items that i want to calculate the user context to.
    } #
    OPTIONAL
      { FILTER EXISTS { ?item  rdf:type  ?itemClass }
        ?userContext  rdf:type       rs:UserContext ;
                  rs:appliedOnItems  ?itemClass ;
                  rs:appliedOnUsers  ?userClass
        OPTIONAL
          { ?userContext  rs:hasWeightIfContextMatched  ?weightMatched }
        OPTIONAL
          { ?userContext  rs:hasWeightIfContextDoesNotMatch  ?weightNotMatched }
        OPTIONAL
          { ?userContext  rs:doNotRecommendInCaseNotMatch  true
            BIND(1 AS ?skip)
          }
        BIND(if(EXISTS { ?user  rdf:type  ?userClass }, coalesce(?weightMatched, "default User Matched"), coalesce(?weightNotMatched, "default User not matched")) AS ?weight)
      }
    BIND(if(bound(?weight), ?weight, "no user context found for this item") AS ?finalWeight)
    FILTER ( ! bound(?skip) )
  }

它可以处理我拥有的数据,但是我现在只有一个测试数据,所以我想问你是否正确

更新3

我的查询生成以下字段:

item skip ...

并且过滤器会删除确实具有跳过绑定的行,但假设一个项目有两行,如下所示:

item skip

A 1

A

A

因此,就我而言,我将只删除第一行,我需要知道是否可以删除该项目的所有行。

约书亚·泰勒(Joshua Taylor)

有很多方法可以做到这一点。这是一个获取每个商品总重量的商品,然后检查该商品是否具有不推荐标志,如果有,则使用0作为总重量:

select ?item (if(bound(?skip), 0.0, ?sumWeight_) as ?sumWeight) {
  { select ?item (sum(?weight) as ?sumWeight_) where {
      ?item :hasContext/:weight ?weight .
    }
    group by ?item
  }
  bind(exists { ?item :hasContext/:doNotRecommend true } as ?skip)
}
----------------------------
| item         | sumWeight |
============================
| :item        | 0.0       |
| :anotherItem | 0.0       |
----------------------------

从概念上讲,此查询为每个项目检查一次,是否其上下文中的任何内容将其标记为不可推荐。我认为这是相对有效的。

绑定(存在{...}作为?跳过)

需要注意的是组合绑定存在您已经知道绑定是如何工作的,因为您已经使用了很多次。bind(expr as?variable)计算表达式expr并将其分配给变量?variable你可能使用存在和(不存在)的过滤器之前的表达式。如果括号内的模式在图中匹配,则存在{…}为true,否则为false。不存在的{…}与之相似,但是相反。图案

?item :hasContext/:doNotRecommend true

只是模式的简写,使用属性路径:

?item :hasContext ?something .
?something :doNotrecommend true .

在这种情况下,如果存在该模式,那么我们要跳过该项目的总权重,而使用零。

选择

如果您愿意计算所有项目的总和,然后排除那些至少具有非推荐上下文的项目,那么您也可以这样做。诀窍只是弄清楚如何计算跳过次数:

select ?item (sum(?weight_) as ?weight){
  ?item :hasContext ?context .
  ?context :weight ?weight_ .
  bind(exists { ?context :doNotRecommend true } as ?skip)
}
group by ?item
having (sum(if(?skip,1,0)) = 0)

注意事项

你提到过

我知道我总是可以在此查询的更高级别上运行另一个查询并解决它,或者我可以使用不存在的过滤器来解决它,但是我希望在同一查询中解决它,因为我应该是一个最小的数据,而在我的本体中,获得重量和这些对象是一个很长的查询

上面的解决方案首先计算和权重,然后确定要使用和丢弃的权重。这意味着有一些不必要的计算。您的解决方案执行类似的操作:即使没有相同的其他上下文具有doNotRecommend属性,它也会为没有:doNotRecommend属性的上下文计算权重。如果您真的想避免不必要的计算,则应先确定哪些项目是可推荐的,然后为这些项目计算分数,确定哪些项目不值得推荐,并为这些项目返回零。

很容易获得哪些项目的清单:

select distinct ?item ?skip {
  ?item :hasContext ?anything .
  bind(exists{ :hasContext/:doNotRecommend true} as ?skip)
}

会做的很好。但是,由于您想对skippable和non-skipable值执行不同的操作,并且这可能采用两种选择的并集形式,因此,您遇到的问题是必须重复执行每个子查询中都有相同的子查询。(或者使用存在于一个中而不存在于另一个中,这实际上是在重复相同的查询。)它将很快变得很丑陋。它可能看起来像这样:

select ?item ?weight {
  {
     #-- get non recommendable items and
     #-- set their weights to 0.0.
     select distinct ?item (0.0 as ?weight) {
       ?item :hasContext/:doNotRecommend true      #-- (*)
     }
  }
  union
  {
     #-- get recommendable items and
     #-- their aggregate weights
     select ?item (sum(?weight_) as ?weight) {
       #-- find the recommendable items
       { select distinct ?item {
           ?item :hasContext ?x .
           filter not exists { ?item :hasContext/:doNotRecommend true }   #-- (*)
         }
       }
       #-- and get their context's weights.
       ?item :hasContext/:weight ?weight_
     }
     group by ?item
  }
}
-------------------------
| item         | weight |
=========================
| :item        | 0.0    |
| :anotherItem | 0.9    |
-------------------------

我认为问题在于,标有(*)的行确实在做同一件事。其他计算不会多次发生,这很好,但是我们仍在检查每个项目是否值得推荐两次。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

sparql检查是否存在某个属性,并将答案设为零

来自分类Dev

检查属性是否存在

来自分类Dev

检查某个页面中是否存在xpath

来自分类Dev

检查嵌套属性是否存在

来自分类Dev

检查是否存在多个属性

来自分类Dev

检查是否存在多个属性

来自分类Dev

通过属性名称检查属性是否存在

来自分类Dev

要检查数组中是否已存在某个元素,然后检查是否存在,请将其删除

来自分类Dev

使用单词字典检查是否存在某个单词

来自分类Dev

检查是否存在某个行,否则选择其他行

来自分类Dev

如何检查动态表中是否存在某个项目?

来自分类Dev

检查某个目录中是否存在文件夹

来自分类Dev

对 hstore 属性的 Activerecord 范围查询,检查属性是否为零?

来自分类Dev

打字稿检查属性是否存在

来自分类Dev

JS检查深层对象属性是否存在

来自分类Dev

如何检查动态属性是否存在

来自分类Dev

检查Javascript对象中是否存在属性

来自分类Dev

检查是否存在对象属性

来自分类Dev

检查AppDelegate中的方法/属性是否存在

来自分类Dev

猫鼬findById检查属性是否存在

来自分类Dev

如何检查设置中是否存在属性?

来自分类Dev

尝试检查nuxt js是否存在属性

来自分类Dev

Freemarker检查变量是否存在并且不为零

来自分类Dev

JScript检查元素是否存在并将其删除

来自分类Dev

VBA查找N / A错误并将其设为零

来自分类Dev

iOS如何检查数组的值是否包含某个值并将其显示出来

来自分类Dev

(JAVA)检查输入字符串是否包含某个单词(确定的)并将其删除

来自分类Dev

MongoDB检查属性是否存在(以及子属性)

来自分类Dev

检查属性是否存在DataTable.ExtendedProperties属性

Related 相关文章

热门标签

归档