0
votes

Suppose I have two xml documents : Document 1:

<item>
  <item_id> 001 </item_id>
  <color>blue</color>
</item>

Document 2:

<item>
  <item_ref_id>abc</item_ref_id>
  <color>blue</color>
</item>

Now for inferencing, I will define a triple as:

<item_ref_id> <http://www.w3.org/2002/07/owl#sameAs> <item_id>

If I write a SPARQL query for fetching document2 with <item_id> = abc, it should work. Is this possible via inferencing, how can we do this kind of stuff through MarkLogic. What all triples are needed to achieve this?

Updating the approach which i used as:

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

 declare namespace s = "http://www.w3.org/2005/sparql-results#";

for $doc in sem:query-results-serialize(sem:sparql( "SELECT ?s WHERE 
{?s <http://www.w3.org/2002/07/owl#sameAs>    
<productId>}"),"xml")//s:uri/text()

return cts:element-value-query(xs:QName($doc), '001')

The result which i get from this is: cts:element-value-query(fn:QName("","id"), "001", ("lang=en"), 1)
cts:element-value-query(fn:QName("","productId"), "001", ("lang=en"), 1)

I have few questions regarding this: 1. Is my approach correct for solving this scenario which i have mentioned above ? 2. I am not able to use the result of sparql query and expand the query for searching the document, can you please update what i am doing wrong in this?

4

4 Answers

2
votes

However, you can also leverage the sameAs triple in MarkLogic document search. While processing a search call, you could identify searches based on item_id. You could then expand item_id using values returned from the SPARQL call alike:

select * { ?s <http://www.w3.org/2002/07/owl#sameAs> <item_id> }

And then run the expanded search query.

-- addition --

The code you shared in your updated question is almost there, you have successfully extrapolated from productId to id. You only need to wrap the element queries into an and-query, and pass it to cts:search. Something like:

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

declare namespace s = "http://www.w3.org/2005/sparql-results#";

let $qnames :=
  for $id in sem:query-results-serialize(sem:sparql( "SELECT ?s WHERE 
    {?s <http://www.w3.org/2002/07/owl#sameAs     
      <item_id>}"),"xml")//s:uri/text()

  return xs:QName($id)

return cts:search(collection(), cts:element-value-query($qnames, '001'))

HTH!

1
votes

You can only inference over RDF data, so you would have to convert the XML structure to triples. You could then define a rule like this:

rule "item_ref_id" construct {
  ?s <item_id> ?o
} {
  ?s <item_ref_id> ?o
}

And after that you only need to select the rule when running SPARQL to make use of it.

HTH!

0
votes

I have added relationship for the above mentioned scenario in this way:

(item1 uri)---> has unique --> id ---> same as <--- productid <---- has unique <--- (item2 uri)

item_id ---> (hasValue-def) ---> 001

item_ref_id---> (hasValue-def) ----> abc

After adding the following triples i could search the item using item_id for both the items, using inferencing as:

import module namespace sem = "http://marklogic.com/semantics" at "/MarkLogic/semantics.xqy";
declare namespace s = "http://www.w3.org/2005/sparql-results#";


for $doc in sem:query-results-serialize(
sem:sparql("SELECT * WHERE {?s <has-unique-key as#>/<https://www.w3.org/TR/2002/WD-owl-ref-20021112/#hasValue-def>/<http://www.w3.org/2002/07/owl#sameAs>*  <001>}"),     "xml")//s:uri/text()
return fn:doc($doc)
0
votes

@grtjn

I have got the solution for that fix, which resolves query to search for both id's, please check this:

Document1:

<item>
  <item_id> 001 </item_id>
  <color>blue</color>
</item>

Document2:

<item>
  <item_ref_id>abc</item_ref_id>
  <color>blue</color>
</item>

Triple:

<sem:triple>
  <sem:subject>item_ref_id</sem:subject>
  <sem:predicate>http://www.w3.org/2002/07/owl#sameAs</sem:predicate>
  <sem:object>item_id</sem:object>
</sem:triple>

With this structure above, i run the following query (modified from the solution), and it resolves the document for both id's with item_id:

import module namespace sem = "http://marklogic.com/semantics" 
at "/MarkLogic/semantics.xqy";
declare namespace s = "http://www.w3.org/2005/sparql-results#";

for $id in  sem:query-results-serialize(
sem:sparql( "SELECT ?s WHERE {?s <http://www.w3.org/2002/07/owl#sameAs> <item_id>}"),"xml")//s:uri/text() 


return cts:search(collection(),cts:and-query((
cts:element-value-query(xs:QName($id), '001'))
))

It works if i pass 'abc' too for the search.

Thanks for the idea of how to use this, it helped me resolve this problem.