我有以下数据:
<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>
到目前为止,我有2个解决方案:
<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>
有更有效的方法吗?
也许可以利用多个群体的优势?
更新资料
目前,我的代码的一个主要问题是它的性能高度取决于哪个表更大。例如,在第二个表较大的情况下,第一个解决方案更好,反之亦然。
最佳答案
您的解决方案对我来说看起来很合理。在像加入联合优化的Saxon-EE这样的处理器上,它的性能要比没有加入优化的处理器(例如Saxon-HE)上的性能好得多。如果要手动优化它,最简单的方法是切换到使用XSLT:使用key()
函数替换过滤器表达式$t1/Subject[Id = $foriegnId]
,在没有优化的情况下,它会针对所选的每个元素在第二个文件中搜索一次在第一个文件中。
关于xpath - 有效地对Xquery中两个文档(内部联接)中存在的元素进行分组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34091441/