Jackrabbit搜索加入的节点

Rup*_*Rup 6 jackrabbit jcr crx aem

我在Jackrabbit存储库中标记了对象(实际上是Adobe/Day CQ的CRX,但我认为这是Jackrabbit代码):

  • asset:tags = A,B
    • 子资产数据1:tags = A,C,E
    • 子资产数据2:tags = D,E

我想查询父资产的标签集和一个子集的并集,即"BC"与资产匹配,因为我们在父节点和子节点1中有,但"CD"不匹配,因为没有组合父项和一个匹配的子项,因为C和D在不同的子数据节点之间拆分.

有没有办法在Jackrabbit做到这一点?我们可以编写一个XPath查询

\\element(*, dam:Asset)[(@tags = 'C' or *\@tags='C')
                        and (@tags = 'D' or *\@tags='D')]
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为XPath似乎并不保证*加入的子资产是相同的,即这意味着"任何孩子都有C/D",因此将匹配我的资产,因为1个以上的孩子有C和1+孩子们有一个D.相反,我可以使用JCR-SQL2

SELECT * FROM dam:Asset as asset
  LEFT OUTER JOIN nt:unstructured as child ON ISCHILDNODE(child,asset)
  WHERE (asset.tags = 'C' or child.tags = 'C')
    AND (asset.tags = 'D' or child.tags = 'D')
Run Code Online (Sandbox Code Playgroud)

SELECT DISTINCT在JCR-SQL2中没有:如果我搜索"B E",我会将此资产返回两次,因为这会匹配asset + child1和asset + child2.

我可以在Java中对查询结果进行后处理,即筛选出第一种情况的误报匹配或者过滤掉第二种情况的重复结果,但是我很担心这会如何影响分页性能:我需要扫描更多节点比清除坏节点所需要的,我需要扫描批次以计算正确的分页结果大小.对于第二个SQL2案例,这应该更便宜,因为如果我的搜索是有序的,我可以单独根据节点路径发现重复,并且所有重复都是连续的,所以我只能通过便宜的扫描找到给定页面的数据,但希望无需阅读每个结果的整个节点,但我不知道扫描所有结果的分页计数的成本,即使对于简单的仅路径情况.

我们考虑的另一种选择是将标签非规范化为单个节点.在这种情况下,为了保持搜索准确,这必须意味着在每个子节点中创建一个新的combined_tags属性,并仅对该组子节点执行所有搜索.然而,如果我们匹配同一资产下的两个子节点,这仍然会遇到明显的问题.

谢谢你的任何建议.这已经是一个大型实例,需要进一步扩展.我已经看到其他问题,说ModeShape是一个JCR实现确实有,SELECT DISTINCT但我认为只是为了那个切换到ModeShape必须是最后的手段,如果确实可以在ModeShape上托管CQ.


我们现在提出的一个想法是计算资产标签和子标签的每个联合,并将标签组合成单个字符串,然后将每个值写为资产的多值属性,即asset + child1 ="ABC E"和资产+ child2 ="ABD E",所以我们得到

  • asset:tags = A,B; tagUnions ="ABC E","ABD E"

只要我们定义一个固定的顺序,用于将标签组合成一个字符串(例如按字母顺序排列),我们就可以使用tagUnions LIKE '%B%C%'(除了我在实际情况下在标签之间使用适当的分隔符)来搜索任何组合.虽然这可以在我们看到的情况下工作但我并不喜欢它:每个资产+孩子可能有大量标签,所有名称都比单个字母更长,这意味着我们最终将使用长字符串LIKE对所有字符串执行查询它们可能无法有效索引.

另一种观点是制作一个位掩码:定义A = 1,B = 2等,然后在此处存储一个多值整数数组,然后进行逐位比较.然而,这可能仅限于64个不同的标签,因为我们有1000多个,我认为我们不能这样做 - 即使JCR支持按位操作,我预计它不会.

所以我仍然在寻找一个干净的类似数据库的解决方案.你错过了我提出的赏金,但仍然有任何帮助的嘀嗒声,投票和感激之情.

MrG*_*mez 1

来自Apache Jackrabbit 邮件列表

是的,不幸的是不支持联合查询。任何有关该领域的工作将不胜感激。

同时,最好的解决方法可能是执行两个单独的查询,并通过组合两个结果集在应用程序代码中显式执行并集。

所以,这是一个选择。查看您提供的 SQL:

但 JCR-SQL2 中没有SELECT DISTINCT:如果我搜索“B E”,我将返回该资产两次,因为它同时匹配 asset+child1 和 asset+child2。

我查看了 Jackrabbit 支持的可能解决方案,却空手而归。但是,我同意这里提出的解决方案:

我所做的是使用适当的 ORDER BY 进行简单的 SELECT...然后每次我使用一行时,我都会确认它与之前的不同:-)

(保留原文。)

虽然这ORDER BY可能是可疑的,除非您需要数据库支持的排序,但是否有什么因素阻止您在控制器中构建哈希集以使用 JCR API 将结果限制为仅唯一值?