您如何使用 Optic API 连接具有相似值的视图?

How do you join views with similar values with the Optic API?

我想使用光学 API 连接两个视图。联接看起来像这样:

xquery version "1.0-ml";
import module namespace op="http://marklogic.com/optic" at "/MarkLogic/optic.xqy";

let $qs := op:from-view("Samplestack", "QnA")
let $users := op:from-view("Samplestack", "Contributors")
return $qs
=> op:join-inner($users, op:on("Asker", "ContributorUserName"))
=> op:select(("QnATitle", "QVoteCount", "Asker", "UserReputation"))

问题是 "ContributorUserName" 和 "Asker" 这两列并不完全相同。 "Asker" 的前缀为 "username."。

所以我需要连接 "username." 和 "ContributorUserName" 的值。

根据 Docuementation i can call somehow the concat function within in the plan and therfore do not have to use the function op:call().

但我无法让它工作。

查询应该能够通过 select() 操作和连接前的表达式修改视图,如下图(未测试)所示:

=> op:join-inner(
    $users => op:select((op:as("PrefixedUserName", ofn:concat((
        "username.",op:col("ContributorUserName")
        ))), ...otherNeededColumns...)), 
    op:on("Asker", "PrefixedUserName")
    )

您可能已经知道,该模块必须导入 ofn 模块才能访问 concat() 表达式函数:

import module namespace ofn="http://marklogic.com/optic/expression/fn"
    at "/MarkLogic/optic/optic-fn.xqy";

可以找到 XQuery 库的所有命名空间 here

唯一需要注意的是(至少目前)在表达式上的连接会强制连接到 enode,而不是在 dnode 上执行分布式连接。

因此,如果结果集很大,在 TDE 中执行串联可能会提高性能,必要时创建两列并使用适合查询的列。或者,更好的是,修剪 TDE 中其他 Asker 值的前缀(同样,必要时创建两列)。

希望对您有所帮助,