I am new to XQuery 3.0 and trying to create a simple multi-filter search algorithm.
What I want to do is, check if a parameter is supplied and if so, add it to the query.
This is what I have in my mind:
let $query := doc("music.xml")//music/album
if (request:get-parameter('type', false)) then
let $query := $query[ @type=request:get-parameter('type', '') ]
else
let $query := $query
if (request:get-parameter('title', false)) then
let $query := $query[ @title=request:get-parameter('title', '') ]
else
let $query := $query
if (request:get-parameter('artist', false)) then
let $query := $query[ @artist=request:get-parameter('artist', '') ]
else
let $query := $query
This is incorrect, obviously. Any help to make it correct?
The simplest pattern would be as follows, creating variables for each possible request parameter (supplying a default value for each as the empty sequence), and then in the return clause, check for the presence of each parameter, one at a time:
This code assumes that
<type>
,<title>
, and<artist>
are child elements of<album>
, and we check for an exact match for the parameters supplied. You could change thetitle = $title
comparison tocontains(title, $title)
for case sensitive literal string matches,matches(title, $title, 'i')
for case insensitive regex searches, or a full text index likeft:query(title, $title)
if you configured your index for a full text index on<title>
elements, etc.The weakness of this approach is that we've hard-coded a strict order of priority for the parameters that affect in the query. If a
type
parameter is supplied, the queries ontitle
andalbum
wouldn't be considered even if they were supplied.To chain them together so that any and all supplied parameters are queried, you could take the following approach:
I supplied sample data just to confirm for myself and others testing the code that this works. The comparisons in the return clause are only evaluated if the parameters are supplied. This code assumes at most one value per parameter; some adjustments would be need to made if you were allowing multiple values for each parameter.