2013-02-28 2 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». Но я не могу понять, как искать узлы, которые не имеют свойств, содержащих слово «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

Вы должны использовать JOIN пункт, но использовать OR в предложении WHERE:

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')) 

Это создает два селекторов parent и child, и использует ISCHILDNODE присоединяйте критерии, чтобы узлы в селекторе были дочерними узлами в селекторе 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' (где тип соединения по умолчанию имеет значение «INNER», как SQL-99). –