Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MarkLogic: convert string to path expression in cts:search

How can I create a function in MarkLogic that takes an XPath as a string and then passes it to the cts:search function?

I want to do something like this:

xquery version "1.0-ml";

declare namespace local = "http://www.local.com/" ;

declare function local:xpath-search($xpath as xs:string, $collection as xs:string, $limit  as xs:string) {
let $valid := cts:valid-index-path($xpath,fn:false())
let $results := cts:search(xdmp:value($xpath), cts:and-query(()) ) [position() < 100]
return 
    if ($valid = false()) then "xpath is invalid"
    else (
        if ($results = '') then "no results were found"
             else $results
        )
    } ;


local:xpath-search('//p', '', '')

But, I'm getting the "expression is unsearchable" error.

like image 402
cascavel Avatar asked Feb 23 '26 10:02

cascavel


2 Answers

Use http://docs.marklogic.com/search:search and supply it with the <searchable-expression> option.

The search:search function already implements what you want. Under the hood it calls cts:search and supplies the searchable-expression using xdmp:value. You could do that to, but search:search has already been written and tested.

In passing, using path-based searchable expressions with cts:search is something of a trap for the unwary. In most cases it is better to use collection() as the first argument to cts:search, matching the entire database. Then use a cts:query for the second parameter, to match the documents you are interested in.

But what about //p? It's important to understand that MarkLogic indexes fragments, not elements. By default, fragments are documents. You can change that: you can even fragment at the //p level. But in most cases it's a bad idea. You're probably better off using cts:search to match documents, and cts:highlight to find matches in paragraphs. The search:search function supports that, too.

like image 191
mblakele Avatar answered Feb 25 '26 04:02

mblakele


Cascavel:

You could try expressing the entire cts:search() as a string (concatenating the static parts with the path) and invoking it with xdmp:value or xdmp:eval.

  • http://docs.marklogic.com/xdmp:value
  • http://docs.marklogic.com/xdmp:eval

Hoping that helps,

Erik Hennum

like image 30
ehennum Avatar answered Feb 25 '26 04:02

ehennum



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!