1

I have following 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>`

This is the SPARQL query I am using to calculate sum of these quantities:

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

And the result I get is this -> "0"^^xs:integer instead of 25. Can you please suggest what is wrong in this.

Dave Cassel
  • 8,352
  • 20
  • 38
Harshit Saklecha
  • 100
  • 1
  • 10
  • I don't have a MarkLogic instance up and running... 1) are you sure is a valid predicate? Like, what do you get from `select * where { ?s ?p }` 2) if that query works, are your quantities of a numeric type? It looks to me like they are strings and need to be converted. – Mark Miller May 03 '17 at 17:56
  • Yeah the predicate works fine, but how to convert them into numeric type, i tried storing them with ^^xs:integer but didnt worked – Harshit Saklecha May 03 '17 at 19:16
  • Can you convert your MarkLogic triples into standard RDF? I'd be glad to write a complete solution for you. – Mark Miller May 03 '17 at 19:17
  • yeah i will do that, will the solution work for marklogic too – Harshit Saklecha May 03 '17 at 19:18
  • Hey Mark i dont know how to convert this to rdf trilple, can you please provide solution acccording to that, i will check it it helps – Harshit Saklecha May 05 '17 at 05:54

2 Answers2

1

Marklogic is a very powerful and versatile tool. Having said that, the way it handles RDF & SPARQL is at least a little non-standard in my opinion.

In the future, you could probably read this: https://docs.marklogic.com/sem:rdf-serialize to learn how to convert MarkLogic's native representation of triples into standard RDF.

Now I'm not an XML expert, but I don't think your triples block is valid XML. If it were, you could write an XSLT transformation to turn it into RDF XML.

I did a little manual tidying to get well-formed XML, mainly for illustration purposes:

<?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>

As RDF/XML, that might look something like

<?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>

I created a default namespace of http://wanna.be/, and you can use the default abbreviation to say :hasQty instead of http://wanna.be/hasQty It's a little unusual to use a bare word like <hasQty> as a URI for a term in SPARQL query.

Therefore, to get the sum of quantities, cast each quantity string to an int and then sum:

PREFIX : <http://wanna.be/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
select (sum(xsd:int(?o)) as ?oSum)  where {?s :hasQty ?o}
Mark Miller
  • 3,011
  • 1
  • 14
  • 34
1

I think Mark is on the right track with his casting of string to int. But you can create triples with typed values too. Simplest way is either using SPARQL Update, or code like the following:

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)
))

If you run above from Query Console, and Explore the database after that, you'll notice it created an XML document that looks like this:

<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>

Note the datatype attribute on the sem:object elements. With that datatype attribute in place, your original SPARQL statement works just fine.

By the way, MarkLogic saves triples by default in XML documents containing each about a 100 of them, just for optimal storage. Saving each triple separately is okay, but takes more space. And you can also embed sem:triple elements within other XML documents, those get recognized too. This blog article might interest you, it gives some more background on triples in MarkLogic:

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

HTH!

grtjn
  • 20,254
  • 1
  • 24
  • 35
  • Agreed, nice explanation, but how do you define the datatype also for triples in the above triple definition ? – Harshit Saklecha May 17 '17 at 09:34
  • What triple definition do you mean exactly? The `sem:object` element? Put a `datatype` attribute on it. For XQuery code you could use [sem:typed-literal](http://docs.marklogic.com/sem:typed-literal). In SPARQL you can use the xsd:int cast as mentioned in the last few lines of Mark's answer.. – grtjn May 17 '17 at 19:14