[MarkLogic Dev General] Referencing astringvariablewithincts:search

Danny Sokolsky dsokolsky at marklogic.com
Tue Jun 26 19:30:20 PDT 2007


While xdmp:eval is fine and useful for many things, there are a few
reasons I know of to avoid xdmp:eval.

First, xdmp:eval starts a completely new context, which means the new
query has to be parsed from scratch and evaluated.

Second, because it always starts a new context, and because the XQuery
main module does not exist on the filesystem or in a database, the
xdmp:eval call cannot be cached (and therefore must incur that overhead
each time it is called).  Therefore it is more efficient to call
xdmp:invoke.

These two issues can affect performance, although they might still
perform fine for many applications.

The other reason I know of, and perhaps a more serious one, is that it
can potentially open you up to things analagous to SQL Injection Bugs
(google returns over a million hits on this topic).  These are bugs
which can potentially allow malicious users to issue arbitrary queries
into your system.

I hope that helps some.
-Danny

-----Original Message-----
From: general-bounces at developer.marklogic.com
[mailto:general-bounces at developer.marklogic.com] On Behalf Of Mattio
Valentino
Sent: Tuesday, June 26, 2007 7:15 PM
To: General Mark Logic Developer Discussion
Subject: Re: [MarkLogic Dev General] Referencing
astringvariablewithincts:search


Sorry.  One more follow-up question.

This discussion started from my assumption that xdmp:eval() works but it
may not be the best way to go, and your feedback implies the same. Why
is that?  What's the issue with using xdmp:eval()?  I've been looking in
the docs and I found anything yet.



On 6/26/07, Danny Sokolsky <dsokolsky at marklogic.com> wrote:
> You cannot pass that string in via XCC and have it used as a 
> cts:query.
>
>
> To make this work, you will have to move the code that parses your 
> input into a cts:query  from your .net/java code into your XQuery 
> code.  For example, you can pass in two string variables from the 
> .net/java side:
>  *  "or" to signify it is an or-query.
>  *  "blues jazz" for the words to be queried.
>
> Your XQuery module on the MarkLogic Server side might then look 
> something like this (this is an extremely simple query 
> parser/generator that simply tokenizes the input on spaces):
>
>  define variable $query-type as xs:string external
>  define variable $query as xs:string external
>
>  let $query-tokens := fn:tokenize(fn:normalize-space($query), " ")  
> let $ctsquery :=
>      for $x in $query-tokens
>      return
>      cts:word-query($x, ("case-insensitive", "diacritic-insensitive") 
> )  let $newquery :=
>     if ( $query-type = "or" )
>     then cts:or-query($ctsquery)
>     else cts:and-query($ctsquery)
>  return
>  <results>
>    <cts-query-expr>{$newquery}</cts-query-expr>
>    <search>{xdmp:estimate(cts:search(doc(), $newquery))}</search>  
> </results>
>
> and you can run this code with something like this:
>
>  xdmp:invoke("invoke.xqy", ((xs:QName("query-type"), "or"),
>                           (xs:QName("query"), "blues jazz")))
>
> The other alternative you have is to construct the entire search on 
> the .net/java side, including the cts:search and the cts:query, and 
> then send in the whole query to execute via xcc.
>
> -Danny
>
_______________________________________________
General mailing list
General at developer.marklogic.com
http://xqzone.com/mailman/listinfo/general


More information about the General mailing list