2016-12-24 10 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 절에서 각 매개 변수의 존재를 확인하십시오. 시간 :

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> 요소에 전체 텍스트 인덱스에 대한 색인을 구성하는 경우 ft:query(title, $title) 같은 전체 텍스트 인덱스를 들어, 대소 문자를 구분 문자 문자열 일치하는 contains(title, $title)

matches(title, $title, 'i')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 절의 비교는 매개 변수가 제공된 경우에만 평가됩니다. 이 코드는 매개 변수 당 최대 하나의 값을 가정합니다. 각 매개 변수에 대해 여러 값을 허용하는 경우 일부 조정이 필요합니다.

+0

감사합니다. @joewiz, 내 구세주 야. – yenerunver

+0

잘 듣고;) – joewiz