2016-12-24 14 views
1

XQuery 3.0が初めてで、単純なマルチフィルター検索アルゴリズムを作成しようとしています。XQueryマルチフィルター検索アルゴリズム

私がしたいのは、パラメータが指定されているかどうかを確認し、そうであればそれをクエリに追加します。

これは私が私の心に持っているものです。

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 

これは明らかに、間違っています。それを正しいものにする助け?

答えて

2

最も単純なパターンは次のように(空のシーケンスとしてそれぞれのデフォルト値を与える)各可能なリクエストパラメータの変数を作成すること、及びその後、return節では、各パラメータが存在するかどうかを確認、A 1つになります時間:

xquery version "3.0"; 

let $albums := doc("music.xml")//music/album 
let $type := request:get-parameter('type',()) 
let $title := request:get-parameter('title',()) 
let $artist := request:get-parameter('artist',()) 
return 
    if ($type) then 
     $albums[type = $type] 
    else if ($title) then 
     $albums[title = $title] 
    else if ($artist) then 
     $albums[artist = $artist] 
    else 
     $albums 

このコードは<type><title>、および<artist><album>の子要素であり、我々は指定されたパラメータのための完全な一致を確認することを前提としています。あなたは<title>要素でフルテキストインデックスのためのあなたのインデックスを構成している場合は、

など、大文字と小文字を区別リテラル文字列の一致、大文字小文字を区別しない正規表現検索の matches(title, $title, 'i')、または ft:query(title, $title)などのフルテキストインデックスの contains(title, $title)から title = $title比較を変更することができますこのアプローチの弱点は、クエリで影響を与えるパラメータの優先順位を厳密にハードコーディングしていることです。 typeパラメータが指定された場合、 titlealbumのクエリは提供されても考慮されません。任意およびすべての指定されたパラメータが照会されるように、彼らは一緒に、あなたは次のようなアプローチを取ることができるチェーンへ

は:

xquery version "3.0"; 

let $albums := 
    <albums> 
     <album><type>country</type><title>Holiday Classics</title><artist>Jane</artist></album> 
     <album><type>country</type><title>Lonesome Cowboy</title><artist>Jim</artist></album> 
     <album><type>country</type><title>Lonesome Holiday</title><artist>Jane</artist></album> 
    </albums>//album 
let $type := request:get-parameter('type',()) 
let $title := request:get-parameter('title',()) 
let $artist := request:get-parameter('artist',()) 
return 
    $albums 
     [if ($type) then type = $type else true()] 
     [if ($title) then title = $title else true()] 
     [if ($artist) then artist = $artist else true()] 

私は自分自身と、これが機能することを、コードをテストする他人のために確認するためのサンプルデータを供給しました。 return句での比較は、パラメータが指定されている場合にのみ評価されます。このコードでは、パラメータごとに最大で1つの値を仮定しています。各パラメータに複数の値を許可している場合は、いくつかの調整が必要になります。

+0

@joewizありがとう、あなたは私の救世主だ:)聞いて良い – yenerunver

+0

;) – joewiz