如何在带有三元组的 marklogic sparql 查询中使用像 SUM 这样的聚合函数?

How to use aggregate function like SUM in marklogic sparql query with triples?

我有以下三元组:

<?xml  version="1.0" encoding="UTF-8"?>
<sem:triples xmlns:sem="http://marklogic.com/semantics">
  <sem:triple>
    <sem:subject>item1</sem:subject>
    <sem:predicate>hasQty</sem:predicate>
    <sem:object>20</sem:object>
  </sem:triple>
</sem:triples>


<?xml  version="1.0" encoding="UTF-8"?>
<sem:triples xmlns:sem="http://marklogic.com/semantics">
  <sem:triple>
    <sem:subject>item2</sem:subject>
    <sem:predicate>hasQty</sem:predicate>
    <sem:object>5</sem:object>
  </sem:triple>
</sem:triples>`

这是我用来计算这些数量总和的 SPARQL 查询:

select (SUM(?p) as ?p) where { ?s <hasQty> ?p}

我得到的结果是这个 -> "0"^^xs:integer 而不是 25。 能否请您指出这里有什么问题。

Marklogic 是一个非常强大且用途广泛的工具。话虽如此,在我看来,它处理 RDF 和 SPARQL 的方式至少有点不标准。

将来,您可能会阅读以下内容:https://docs.marklogic.com/sem:rdf-serialize 以了解如何将 MarkLogic 的三元组本机表示转换为标准 RDF。

现在我不是 XML 专家,但我不认为你的三元组块是有效的 XML。如果是,您可以编写 XSLT 转换以将其转换为 RDF XML.

我做了一些手动整理以获得格式正确的XML,主要是为了说明目的:

<?xml version="1.0" encoding="UTF-8"?>
<sem:triples xmlns:sem="http://marklogic.com/semantics">
  <sem:triple>
    <sem:subject>item1</sem:subject>
    <sem:predicate>hasQty</sem:predicate>
    <sem:object>20</sem:object>
  </sem:triple>
  <sem:triple>
    <sem:subject>item2</sem:subject>
    <sem:predicate>hasQty</sem:predicate>
    <sem:object>5</sem:object>
  </sem:triple>
</sem:triples>

作为 RDF/XML,可能看起来像

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
        xmlns="http://wanna.be/"
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

<rdf:Description rdf:about="http://wanna.be/item1">
        <hasQty>20</hasQty>
</rdf:Description>

<rdf:Description rdf:about="http://wanna.be/item2">
        <hasQty>5</hasQty>
</rdf:Description>

</rdf:RDF>

我创建了一个默认命名空间 http://wanna.be/, and you can use the default abbreviation to say :hasQty instead of http://wanna.be/hasQty 在 SPARQL 查询中使用像 <hasQty> 这样的裸词作为术语的 URI 有点不寻常。

因此,要获得数量总和,将每个数量字符串转换为一个 int,然后求和:

PREFIX : <http://wanna.be/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
select (sum(xsd:int(?o)) as ?oSum)  where {?s :hasQty ?o}

我认为 Mark 将字符串转换为 int 的做法是正确的。但是您也可以创建带有类型值的三元组。最简单的方法是使用 SPARQL 更新,或使用如下代码:

xquery version "1.0-ml";

import module namespace sem = "http://marklogic.com/semantics" 
      at "/MarkLogic/semantics.xqy";

sem:rdf-insert((
  sem:triple(sem:iri("item1"), sem:iri("hasQty"), 20),
  sem:triple(sem:iri("item2"), sem:iri("hasQty"), 5)
))

如果您从上面的查询控制台 运行,然后浏览数据库,您会注意到它创建了一个 XML 文档,如下所示:

<sem:triples xmlns:sem="http://marklogic.com/semantics">
  <sem:triple>
    <sem:subject>item1</sem:subject>
    <sem:predicate>hasQty</sem:predicate>
    <sem:object datatype="http://www.w3.org/2001/XMLSchema#integer">20</sem:object>
  </sem:triple>
  <sem:triple>
    <sem:subject>item2</sem:subject>
    <sem:predicate>hasQty</sem:predicate>
    <sem:object datatype="http://www.w3.org/2001/XMLSchema#integer">5</sem:object>
  </sem:triple>
</sem:triples>

注意 sem:object 元素的 datatype 属性。有了 datatype 属性,您的原始 SPARQL 语句就可以正常工作了。

顺便说一句,MarkLogic 默认将三元组保存在 XML 文档中,每个文档包含大约 100 个,只是为了优化存储。单独保存每个三元组是可以的,但需要更多 space。您还可以在其他 XML 文档中嵌入 sem:triple 元素,这些元素也会被识别。这篇博客文章可能会让您感兴趣,它提供了有关 MarkLogic 中三元组的更多背景知识:

http://developer.marklogic.com/blog/managed-vs-unmanaged-triples

HTH!