在Xquery中有效地分组存在于两个文档(内部联接)中的元素

时间:2015-12-04 15:12:46

标签: xpath xquery saxon xquery-3.0

我有以下数据:

<Subjects>
    <Subject>
        <Id>1</Id>
        <Name>Maths</Name>
    </Subject>
    <Subject>
        <Id>2</Id>
        <Name>Science</Name>
    </Subject>
    <Subject>
        <Id>2</Id>
        <Name>Advanced Science</Name>
    </Subject>
</Subjects>

<Courses>
    <Course>
        <SubjectId>1</SubjectId>
        <Name>Algebra I</Name>
    </Course>
    <Course>
        <SubjectId>1</SubjectId>
        <Name>Algebra II</Name>
    </Course>
    <Course>
        <SubjectId>1</SubjectId>
        <Name>Percentages</Name>
    </Course>
    <Course>
        <SubjectId>2</SubjectId>
        <Name>Physics</Name>
    </Course>
    <Course>
        <SubjectId>2</SubjectId>
        <Name>Biology</Name>
    </Course>
</Courses>

我希望从共享共享相同ID的两个文档中有效地获取元素。

我想得到这样的结果:

<Results>
    <Result>
        <Table1>
            <Subject>
                <Id>1</Id>
                <Name>Maths</Name>
            </Subject>
        </Table1>
        <Table2>
            <Course>
                <SubjectId>1</SubjectId>
                <Name>Algebra I</Name>
            </Course>
            <Course>
                <SubjectId>1</SubjectId>
                <Name>Algebra II</Name>
            </Course>
            <Course>
                <SubjectId>1</SubjectId>
                <Name>Percentages</Name>
            </Course>
        </Table2>
    </Result>
    <Result>
        <Table1>
            <Subject>
                <Id>2</Id>
                <Name>Science</Name>
            </Subject>
            <Subject>
                <Id>2</Id>
                <Name>Advanced Science</Name>
            </Subject>
        </Table1>
        <Table2>
            <Course>
                <SubjectId>2</SubjectId>
                <Name>Physics</Name>
            </Course>
            <Course>
                <SubjectId>2</SubjectId>
                <Name>Biology</Name>
            </Course>
        </Table2>
    </Result>
</Results>

到目前为止,我有两个解决方案:

<Results>       
{
   for $e2 in $t2/Course
   let $foriegnId := $e2/SubjectId
   group by $foriegnId
   let $e1 := $t1/Subject[Id = $foriegnId]
   where $e1
   return
      <Result>
         <Table1>
            {$e1}
         </Table1>
         <Table2>
            {$e2}
         </Table2>
      </Result>
}
</Results>

而另一方面:

<Results>       
{
   for $e1 in $t1/Subject
   let $id := $e1/Id
   group by $id
   let $e2 := $t2/Course[SubjectId = $id]
   where $e2
   return
      <Result>
         <Table1>
            {$e1}
         </Table1>
         <Table2>
            {$e2}
         </Table2>
      </Result>
}
</Results>

有更有效的方法吗? 也许利用多个群体?

更新 我的代码目前的一个主要问题是它的性能高度依赖于哪个表更大。例如,在第二个表更大的情况下,第一个解决方案更好,反之亦然。

1 个答案:

答案 0 :(得分:2)

你对我的解决方案看起来很合理。它会像Saxon-EE这样的处理器在连接优化方面表现出色,而不是像Saxon-HE那样(不像Saxon-HE)。如果您想手动优化它,最简单的方法是切换到使用XSLT:使用key()函数替换过滤器表达式$t1/Subject[Id = $foriegnId],在没有优化的情况下,它会搜索您的第二个文件一次对于在第一个文件中选择的每个元素。