简体   繁体   中英

MarkLogic: binding cts:search expression to a variable

In MarkLogic, is it possible to bind a cts:search expression to a variable and then use that variable elsewhere in the XQuery ?

I want to do something like this:

let $query := cts:search(doc(),
                               cts:and-query((
                                  cts:element-attribute-word-query(
                                    xs:QName("para"),
                                    xs:QName("role"),
                                      "intro") ,

                                  cts:element-attribute-word-query(
                                    xs:QName("title"),
                                    xs:QName("role"),
                                      "inline")
                                       ))
                                     )


let $number-of-results := xdmp:estimate($query)

return $number of results

But, I'm not sure how to pass the expression itself, rather than what it returns.

Geert's answer is correct and practical: reuse the cts:query item, not the database access expression. Use the cts:query to query the database as needed.

But in some cases it can be useful to "pass the expression itself" as in the original question. That might seem difficult because XQuery 1.0 doesn't really allow for metaprogramming. Variable bind to sequences of items, which are the result of evaluating expressions. Variables don't bind to unevaluated expressions.

MarkLogic offers a way around this, using functions like http://docs.marklogic.com/xdmp:path or http://docs.marklogic.com/xdmp:value or http://docs.marklogic.com/xdmp:eval for generic expression evaluation. In most cases it's better to bind the cts:query instead, as in Geert's answer. But if you really need metaprogramming, you can build expressions as strings and evaluated them on demand.

let $query := 'cts:search(doc(),
                           cts:and-query((
                              cts:element-attribute-word-query(
                                xs:QName("para"),
                                xs:QName("role"),
                                  "intro") ,

                              cts:element-attribute-word-query(
                                xs:QName("title"),
                                xs:QName("role"),
                                  "inline")
                                   ))
                                 )'
return xdmp:value('xdmp:estimate('||$query||')')

XQuery 3 support in MarkLogic might help with this, but otherwise no. You can put the cts:query part in $query like this though:

let $query := cts:and-query((
                              cts:element-attribute-word-query(
                                xs:QName("para"),
                                xs:QName("role"),
                                  "intro") ,

                              cts:element-attribute-word-query(
                                xs:QName("title"),
                                xs:QName("role"),
                                  "inline")
                                   ))

let $number-of-results := xdmp:estimate(cts:search(doc(), $query))
let $results := cts:search(doc(), $query)

return $number-of-results

HTH!

In the general case you can do exactly what you want, it's just that xdmp:estimate() is a special case that requires an inline searchable expression and not a variable to a searchable expression. That's why xdmp:estimate(cts:search(doc(), $query)) works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM