3

在 Marklogic 中,我想通过将 collection1 中的 doc 的 id 元素连接到 collection2 中的 doc 的 id 元素来在两个集合之间进行搜索。当它匹配时,我需要来自两个集合的结果文档。我有下面的代码,但它很慢。如何使用 cts:search 或 search:search 来实现相同的

for $i in collection('demographic')/individual,
    $j in collection('membership')/membership[enrolleIndividualId/id/text() = $i/individual/id/text()])  
return {$i,$j}
4

1 回答 1

4

更新

我应该注意到您的示例无效 XQuery:return element root { $i, $j }将是有效的。此外,您不应该使用/text()节点选择器,因为它的行为可能违反直觉。您可以直接在 XPath 谓词 ( [enrolleIndividualId/id eq $i/individual/id]) 中比较元素。如果您需要将元素的内容作为字符串,请使用/fn:string()代替。在直接比较单个元素时,/text()我还建议使用原子相等运算符eq代替序列相等运算符。=

原答案:

在 MarkLogic 中实现联接有多种方法,但我首先要质疑您的数据模型。从示例查询中的元素名称来看,您似乎正在使用关系模型 ( individualshave memberships)。MarkLogic 是一个文档数据库,它针对非规范化文档进行了优化。您将更好地处理您的数据并生成individual每个包含相关membership数据的新文档。

话虽如此,以下是加入文档的方法:

首先,您将需要范围索引来编写高性能连接。如果id您的示例查询中的元素对个人来说不是唯一的,您将需要在 和 上的路径范围索引enrolledIndividualId/idindividual/id否则,一个简单的元素范围索引就可以了id

MarkLogic 中最常见的连接模式使用“shotgun-OR”查询;首先从支持范围索引的词典中检索值,然后从这些值构造一个或查询以检索相关文档。这在您的情况下不会直接起作用,因为您想检索联接的双方。您可以对每对文档运行搜索,或者对一侧运行单个搜索,然后为每个文档读取一个附加文档。

对:

for $value in cts:values(cts:path-reference("individual/id"))
return
  cts:search(/,
    cts:or-query((
      cts:and-query((
        cts:collection-query("demographic"),
        cts:path-range-query("individual/id", "=", $value))),
      cts:and-query((
        cts:collection-query("membership"),
        cts:path-range-query("enrolledIndividualId/id", "=", $value))))),
    "unfiltered")

霰弹枪或加迭代:

for $doc in 
  cts:search(/,
    cts:and-query((
      cts:collection-query("demographic"),
      cts:path-range-query("individual/id", "=",
        cts:values(cts:path-reference("individual/id"))))),
    "unfiltered")
return
  cts:search(/,
    cts:and-query((
      cts:collection-query("membership"),
      cts:path-range-query("enrolledIndividualId/id", "=", $doc/individual/id))),
    "unfiltered")

如您所见,每种方法都需要与您要加入的文档/值的数量成比例的 I/O。如果您只需要shotgun-OR(即,根据其他文档的条件查询文档),您只需要发出两个请求,第一次cts:values()调用从词典中检索值,以及cts:search()使用构建的查询调用那些价值观。

注意:cts:query这些示例中使用的对象可以通过该search:resolve()函数与 Search API 结合使用。

鉴于您明显的数据模型,通过将数据处理成单独的、非规范化的文档,您将获得更好的服务。

于 2015-09-22T05:31:07.720 回答