Search code examples
sparqlgeospatialmarklogic

QName for Triples (MarkLogic)


I have been attempting various ways to access the lat and long QName from my triples. An example of my triple data is

<?xml  version="1.0" encoding="UTF-8"?>
<sem:triples xmlns:sem="http://marklogic.com/semantics">
  <sem:triple>
    <sem:subject>http://dbpedia.org/resource/Slantsy</sem:subject>
    <sem:predicate>http://www.w3.org/1999/02/22-rdf-syntax-ns#type</sem:predicate>
    <sem:object>http://www.opengis.net/gml/_Feature</sem:object>
  </sem:triple>
  <sem:triple>
    <sem:subject>http://dbpedia.org/resource/Slantsy</sem:subject>
    <sem:predicate>http://www.w3.org/2003/01/geo/wgs84_pos#lat</sem:predicate>
    <sem:object datatype="http://www.w3.org/2001/XMLSchema#double">59.11666666666667</sem:object>
  </sem:triple>
  <sem:triple>
    <sem:subject>http://dbpedia.org/resource/Slantsy</sem:subject>
    <sem:predicate>http://www.w3.org/2003/01/geo/wgs84_pos#long</sem:predicate>
    <sem:object datatype="http://www.w3.org/2001/XMLSchema#double">28.083333333333332</sem:object>
  </sem:triple>
  <sem:triple>
    <sem:subject>http://dbpedia.org/resource/Slantsy</sem:subject>
    <sem:predicate>http://www.georss.org/georss/point</sem:predicate>
    <sem:object xml:lang="en">59.11666666666667 28.083333333333332</sem:object>
  </sem:triple>
</sem:triples>

Output from SPARQL "DESCRIBE"

@prefix xs: <http://www.w3.org/2001/XMLSchema#> .
@prefix p2: <http://www.w3.org/2003/01/geo/wgs84_pos#> .
<http://dbpedia.org/resource/Slantsy> <http://www.georss.org/georss/point> "59.11666666666667 28.083333333333332"@en ;
                                      a <http://www.opengis.net/gml/_Feature> ;
                                      p2:long "28.0833333333333"^^xs:double ;
                                      p2:lat "59.1166666666667"^^xs:double .

I have seen a similar case in this thread How to create and use GeoSpatial indexes in Marklogic from Sparql

where the Qname was accessed using

fn:QName("http://www.w3.org/2003/01/geo/wgs84_pos#", "lat")

Hence, I tried a similar approach and used

cts:search(/sem:triples,
   cts:element-pair-geospatial-query(
     xs:QName("sem:triples"),
     fn:QName("http://www.w3.org/2001/01/geo/wgs84_pos#", "lat"),
     fn:QName("http://www.w3.org/2001/01/geo/wgs84_pos#", "long"),
     cts:circle(2000, cts:point(59,28)))
)

However, I received an empty query which do not seem to be correct. Any advise would be greatly appreciated Thanks.

===Update=== Finally got it to work as suggested by grtjin. The geospatial index was added using the path

/sem:triples/sem:triple[sem:predicate = 'http://www.georss.org/georss/point']/sem:object

and queried using

cts:search(fn:doc(),
  cts:path-geospatial-query(
  "/sem:triples/sem:triple[sem:predicate = 'http://www.georss.org/georss/point']/sem:object",
  cts:circle(10, cts:point(59,28))
  )
)

Which works and returns the proper results.

However I also attempted to query using

cts:search(fn:doc()/sem:triples,
  cts:path-geospatial-query(
  "/sem:triple[sem:predicate = 'http://www.georss.org/georss/point']/sem:object",
  cts:circle(10, cts:point(59,28))
  )
)

Despite expecting this to work because I should be querying each sem:triples item using the path specified to reach a specific lat,long point. I received an empty query instead. Am I understanding something wrong here?


Solution

  • Would be nice if you could do this, but the element-pair index doesn't work this way unfortunately.

    Firstly, the child elements must be direct children of the indicated ancestor, which is why it speaks of parent rather than ancestor.

    Secondly, you cannot target element values like that. The elements containing lat and long are both sem:object elements.

    I'd suggest using a geospatial path index instead, on something that contains a point, and you happen to have that. This as path reference should work I think:

    sem:triple[sem:predicate = "http://www.georss.org/georss/point"]/sem:object
    

    HTH!