MarkLogic: binding cts:search expression to a variable
Asked Answered
H

3

5

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.

Hydracid answered 11/12, 2013 at 13:12 Comment(0)
T
3

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!

Tempered answered 11/12, 2013 at 14:1 Comment(0)
G
4

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||')')
Goodfornothing answered 11/12, 2013 at 17:26 Comment(0)
T
3

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!

Tempered answered 11/12, 2013 at 14:1 Comment(0)
O
1

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.

Odessa answered 11/12, 2013 at 15:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.