2013-02-28 4 views
1

JCR SQL2에서 전체 텍스트 검색을 수행하려고합니다. 쿼리는 검색 문자열을 포함하는 적어도 하나의 속성을 가진 모든 노드를 반환하거나 동일한 문자열을 포함하는 속성을 가진 자식 노드를 반환해야합니다. ,노드 속성 및 모든 하위 노드에서 JCR SQL2 전체 텍스트 검색

select * from [nt:base] as t where ocm_classname = 'info.magnolia.cv.CurriculumVitae' and contains(t.*, 'java') 

이 첫 번째 부분을 해결 지정된 ocm_classname 단어 '자바'를 포함하는 적어도 하나 개의 속성을 가진 모든 노드를 선택 : 여기에 지금까지 무슨이다. 하지만 'java'라는 단어가 포함 된 속성이 없지만 단어가 포함 된 속성을 가진 자식 노드가있는 노드를 검색하는 방법을 알아낼 수는 없습니다.

<sv:node sv:name="cv1362044004066"> 
    <sv:property sv:name="jcr:primaryType" sv:type="Name"> 
     <sv:value>nt:unstructured</sv:value> 
    </sv:property> 
    <sv:property sv:name="address" sv:type="String"> 
     <sv:value>Chicago, IL</sv:value> 
    </sv:property> 
    <sv:property sv:name="currentDepartment" sv:type="String"> 
     <sv:value>dotNet</sv:value> 
    </sv:property> 
    <sv:property sv:name="currentRole" sv:type="String"> 
     <sv:value>Project Manager</sv:value> 
    </sv:property> 
    <sv:property sv:name="dateOfBirth" sv:type="Date"> 
     <sv:value>1981-01-14T00:05:00.000-05:00</sv:value> 
    </sv:property> 
    <sv:property sv:name="id" sv:type="String"> 
     <sv:value>1362044004066</sv:value> 
    </sv:property> 
    <sv:property sv:name="name" sv:type="String"> 
     <sv:value>John Carpenter</sv:value> 
    </sv:property> 
    <sv:property sv:name="ocm_classname" sv:type="String"> 
     <sv:value>info.magnolia.cv.CurriculumVitae</sv:value> 
    </sv:property> 
    <sv:node sv:name="skills"> 
     <sv:property sv:name="jcr:primaryType" sv:type="Name"> 
      <sv:value>nt:unstructured</sv:value> 
     </sv:property> 
     <sv:node sv:name="collection-element"> 
      <sv:property sv:name="jcr:primaryType" sv:type="Name"> 
       <sv:value>nt:unstructured</sv:value> 
      </sv:property> 
      <sv:property sv:name="level" sv:type="String"> 
       <sv:value>Advanced</sv:value> 
      </sv:property> 
      <sv:property sv:name="name" sv:type="String"> 
       <sv:value>Management</sv:value> 
      </sv:property> 
      <sv:property sv:name="ocm_classname" sv:type="String"> 
       <sv:value>info.magnolia.cv.CVSkills</sv:value> 
      </sv:property> 
     </sv:node> 
     <sv:node sv:name="collection-element"> 
      <sv:property sv:name="jcr:primaryType" sv:type="Name"> 
       <sv:value>nt:unstructured</sv:value> 
      </sv:property> 
      <sv:property sv:name="level" sv:type="String"> 
       <sv:value>Advanced</sv:value> 
      </sv:property> 
      <sv:property sv:name="name" sv:type="String"> 
       <sv:value>Scrum</sv:value> 
      </sv:property> 
      <sv:property sv:name="ocm_classname" sv:type="String"> 
       <sv:value>info.magnolia.cv.CVSkills</sv:value> 
      </sv:property> 
     </sv:node> 
     <sv:node sv:name="collection-element"> 
      <sv:property sv:name="jcr:primaryType" sv:type="Name"> 
       <sv:value>nt:unstructured</sv:value> 
      </sv:property> 
      <sv:property sv:name="level" sv:type="String"> 
       <sv:value>Advanced</sv:value> 
      </sv:property> 
      <sv:property sv:name="name" sv:type="String"> 
       <sv:value>Java</sv:value> 
      </sv:property> 
      <sv:property sv:name="ocm_classname" sv:type="String"> 
       <sv:value>info.magnolia.cv.CVSkills</sv:value> 
      </sv:property> 
     </sv:node> 
     <sv:node sv:name="collection-element"> 
      <sv:property sv:name="jcr:primaryType" sv:type="Name"> 
       <sv:value>nt:unstructured</sv:value> 
      </sv:property> 
      <sv:property sv:name="level" sv:type="String"> 
       <sv:value>Intermediate</sv:value> 
      </sv:property> 
      <sv:property sv:name="name" sv:type="String"> 
       <sv:value>Spring</sv:value> 
      </sv:property> 
      <sv:property sv:name="ocm_classname" sv:type="String"> 
       <sv:value>info.magnolia.cv.CVSkills</sv:value> 
      </sv:property> 
     </sv:node> 
    </sv:node> 
</sv:code> 

답변

4

당신은 절을 조인을 사용하지만, WHERE 절에 OR을 사용할 필요 : 예를 들어,이 노드를 찾을 수 있어야

SELECT parent.* 
FROM [nt:base] AS parent 
INNER JOIN [nt:base] AS child ON ISCHILDNODE(child,parent) 
WHERE parent.ocm_classname = 'info.magnolia.cv.CurriculumVitae' 
    AND (CONTAINS(parent.*, 'java') OR CONTAINS(child.*,'java')) 

이 두 선택기, parentchild를 생성 및 사용 ISCHILDNODEchild 선택 자의 노드가 parent 선택자에있는 노드의 하위 노드인지 확인하기위한 기준을 조인하십시오. 그런 다음 OR 조건을 사용하여 'java'가 포함 된 결과 상위 노드 또는 'java'가 포함 된 하위 노드를 결과에 포함시킵니다.

+0

감사합니다. 도움이되었습니다. 쿼리가이 상태에서 작동하지 않지만 문제를 해결하는 데 도움이되었습니다. 'info.magnolia.cv.CVSkills'가'info.magnolia.cv.CurriculumVitae'의 직접 노드가 아니라는 것을 알 수 있습니다.하지만 중간 노드에 대한 새로운 조인을 추가하면 효과가있었습니다. 또한, 그것은 중복 행을 반환하지만 내가 아는 한 SQL2에는 'distinct'가 없다는 것을 알고 있습니다. – PeterB

+0

또한 'join'이 작동하지 않으며, 오류가 발생하고, 'inner join'을 사용해야합니다. – PeterB

+0

당신은 JSR-283 스펙은 'DISTINCT'를 정의하지 않습니다. 또한'INNER JOIN'을 사용하기 위해 제안 된 쿼리를 업데이트했습니다. JCR2 (예 : ModeShape)의 일부 구현은 JCR-SQL2에 대한 비표준 확장을 지원합니다. 여기에는 DISTINCT 및 JOIN (조인 유형의 디폴트는 SQL-99와 같은 INNER)이 포함됩니다. –