Здесь я вижу два варианта:
- либо вы используете геопространственную функцию, встроенную в MarkLogic, чтобы находить геопространственное перекрытие непосредственно внутри SPARQL, предпочтительно сравнивая свойство RDF, а не значение из индекса пути (все еще неоптимального)
- лучше: предварительно извлечь список документов, соответствующих вашему геопространственному ограничению, и передать это как ограничение в ваш SPARQL (это должно быть очень эффективным)
Что-то вроде:
let $uris := cts:uris((), (), cts:path-geospatial-query("/people_data/location", cts:circle(10, cts:point(59,28))))
return sem:sparql('
SELECT *
WHERE{
?person </posted> ?question .
FILTER (?person = ?people) .
}
', map:entry("people", $uris))
Несколько более удобный и лучше оптимизированный пример, приведенный выше, состоит в том, чтобы переписать его с помощью Optic API. Он разработан специально для обеспечения высокоэффективного способа преодоления разрыва между различными моделями данных.
Экстраполируя на приведенный выше код, я думаю, что он будет читать что-то вроде этого в оптическом коде:
import module namespace op="http://marklogic.com/optic" at "/MarkLogic/optic.xqy";
let $people := op:from-lexicons(
map:entry("people", cts:uri-reference()),
"lexicon"
)
=> op:where(
cts:path-geospatial-query("/people_data/location", cts:circle(10, cts:point(59,28)))
)
let $questions := op:from-sparql('SELECT * WHERE { ?person </posted> ?question. }', "sparql")
return $people
=> op:join-inner(
$questions,
op:on(
op:view-col("lexicon", "people"),
op:view-col("sparql", "person")
)
)
=>op:result()
Немного сложно протестировать его без надлежащих данных и индексов, но я надеюсь, что этого достаточно, чтобы вы начали.
Вступительную документацию вы можете найти здесь:
https://docs.marklogic.com/guide/app-dev/OpticAPI
И ссылку на API можно найти здесь:
https://docs.marklogic.com/op
НТН!