Hugo Koopmans
Hugo Koopmans

Reputation: 1369

Marklogic cts:element-child-geospatial-query is slow but does not need index?

Hi Markloggers out there,

I bump into a strange situation. My experience so far is that I need to set a specific index for cts: functions to perform well. Now I need to search geotagged tweets in de db I use the following query. Seems I do not need teo make specific indexes for cts:element-child-geospatial-query() to run, but performance is poor... what am I missing here?

Query

xquery version "1.0-ml";
declare namespace j = "http://marklogic.com/xdmp/json/basic";

let $lon := 5.470047
let $lat := 51.819565
let $radius := 5.0

let $point := cts:point($lon, $lat)

let $circle := cts:circle($radius,$point)
(:
let $pattern := "/twitter/*"         
let $pointSource := cts:uri-match($pattern)  
:)

(: give back all tweet ids in the circle :)
let $codes := for $p in cts:search(fn:doc(), cts:element-child-geospatial-query(xs:QName("j:geo"), xs:QName("j:point"), $circle))
    return $p//j:id

return fn:count($codes)

One million tweets that have to following elements in them:

<json type="object" xmlns="http://marklogic.com/xdmp/json/basic">
... other stuff ...
<dikwmetadata type="object">
<source type="string">
twitter_nederland
</source>
<timestamp type="string">
2014-03-11T21:19:03.818547
</timestamp>
<data xmlns:j="http://marklogic.com/xdmp/json/basic">
<point_was_tried>
2014-03-11T21:19:03.835457+01:00
</point_was_tried>
<postalcode_was_tried>
2014-03-11T21:19:03.835457+01:00
</postalcode_was_tried>
<geo lastupdate="">
<point>
4.65407742 , 52.28828829
</point>
</geo>
<tags lastupdate=""/>
<postalcodes lastupdate="">
<postal_code>
2135
</postal_code>
</postalcodes>
</data>
</dikwmetadata>
</json>

we added element range index type = string to geo and point elements but no improvement...

Response now 60 seconds...

Any tips?

hugo

Upvotes: 1

Views: 109

Answers (2)

wst
wst

Reputation: 11771

Geospatial indexes are separate from range indexes. You can create them in Admin > Databases > DB-Name > Geospatial Indexes.

In addition to running the query unfiltered, if you simply want to count the number of matching fragments, then you can use xdmp:estimate instead of count:

xdmp:estimate(cts:search(...))

Upvotes: 2

prker
prker

Reputation: 504

You might consider doing the cts:search unfiltered.
cts:search(fn:doc(), cts:element-child-geospatial-query(xs:QName("j:geo"), xs:QName("j:point"), $circle),("unfiltered"))
That would go by the indexes only instead of actually verifying each hit.

Upvotes: 1

Related Questions