使用两个索引的 MarkLogic 光学查询 returns 无结果
MarkLogic optic query using two indexes returns no results
我想使用 MarkLogic 光学器件 API 连接两个范围索引,但不知何故它们不连接。是查询语句写错了还是不能比较使用的索引?
我定义了两个索引:
- 元素属性范围索引 x/@refid
- 范围字段索引'id'
两者都是字符串类型并且定义了相同的排序规则。这两个索引都有我可以使用 cts:values() 函数检索的数据。两者都是巨大的索引,我想使用光学技术加入它们,所以我构建了以下查询:
import module namespace op="http://marklogic.com/optic"
at "/MarkLogic/optic.xqy";
let $subfrag := op:fragment-id-col("subfrag")
let $notfrag := op:fragment-id-col("notfrag")
let $query :=
cts:and-query((
cts:collection-query("latest")
))
let $subids := op:from-lexicons(
map:entry("subid", cts:field-reference("id")), (), $subfrag) => op:where($query)
let $notids := op:from-lexicons(
map:entry("notid", cts:element-attribute-reference(xs:QName("x"), xs:QName("refid"))),
(),
$notfrag)
return $subids
=> op:join-cross-product($notids)
=> op:where(op:eq($notfrag, $subfrag))
=> op:result()
此查询使用连接叉积,当我删除 op:where 子句时,我得到了左右的所有值。我验证了一些是相等的,所以该子句应该只过滤我真正感兴趣的那些行。但不知何故它不起作用,我得到一个空结果。此外,如果我用字符串值替换 op:eq 中的一个值,它不会 return 结果。
当我在 op:eq 运算符(如 op:eq($notfrag, $notfrag))中使用相同的变量时,我得到了结果,所以语句是有效的。只是不是两个指标之间的比较。
我也使用了内部连接和左外部连接的变体,但这些也return没有结果。
我是在比较两个无法比较的索引还是遗漏了一些语句(因为 documentation/example 有点薄)。
(当然我可以不使用光学来解决,但在这种情况下它会很合适)
[更新]
我最终通过更改最终语句使其工作:
return $subids
=> op:join-cross-product($notids)
=> op:where(op:eq(op:col('subid'), op:col('notid')))
=> op:result()
所以你不能在条件中使用片段定义。在此之后,我将 join-cross-product 替换为 join-inner 结构,这应该会更有效率。
为了完整起见,我最初使用了此处找到的 MarkLogic 文档中的示例 (https://docs.marklogic.com/guide/app-dev/OpticAPI#id_87356),特别是最后一个示例,他们使用片段列定义作为 join-inner 中的参数在我的案例中不起作用的声明。
叉积通常只对小行集有用。
将两个引用放在同一个 from-lexicons() 访问器中进行隐式连接,这意味着引擎通过为每个文档构建索引值的本地叉积来形成行。
这样的查询可以表示为:
op:from-lexicons(
map:entry("subid", cts:field-reference("id"))
=>map:with("notid", cts:element-attribute-reference(xs:QName("x"),
xs:QName("refid")))
=>op:where(cts:collection-query("latest"))
=>op:result()
显式连接可以通过以下方式完成:
let $subids := op:from-lexicons(
map:entry("subid", cts:field-reference("id")), (), $subfrag)
=> op:where($query)
let $notids := op:from-lexicons(
map:entry("notid", cts:element-attribute-reference(xs:QName("x"),
xs:QName("refid"))),
(),
$notfrag)
return $subids
=> op:join-inner($notids, op:on($notfrag, $subfrag))
=> op:result()
希望对您有所帮助,
我想使用 MarkLogic 光学器件 API 连接两个范围索引,但不知何故它们不连接。是查询语句写错了还是不能比较使用的索引?
我定义了两个索引:
- 元素属性范围索引 x/@refid
- 范围字段索引'id'
两者都是字符串类型并且定义了相同的排序规则。这两个索引都有我可以使用 cts:values() 函数检索的数据。两者都是巨大的索引,我想使用光学技术加入它们,所以我构建了以下查询:
import module namespace op="http://marklogic.com/optic"
at "/MarkLogic/optic.xqy";
let $subfrag := op:fragment-id-col("subfrag")
let $notfrag := op:fragment-id-col("notfrag")
let $query :=
cts:and-query((
cts:collection-query("latest")
))
let $subids := op:from-lexicons(
map:entry("subid", cts:field-reference("id")), (), $subfrag) => op:where($query)
let $notids := op:from-lexicons(
map:entry("notid", cts:element-attribute-reference(xs:QName("x"), xs:QName("refid"))),
(),
$notfrag)
return $subids
=> op:join-cross-product($notids)
=> op:where(op:eq($notfrag, $subfrag))
=> op:result()
此查询使用连接叉积,当我删除 op:where 子句时,我得到了左右的所有值。我验证了一些是相等的,所以该子句应该只过滤我真正感兴趣的那些行。但不知何故它不起作用,我得到一个空结果。此外,如果我用字符串值替换 op:eq 中的一个值,它不会 return 结果。
当我在 op:eq 运算符(如 op:eq($notfrag, $notfrag))中使用相同的变量时,我得到了结果,所以语句是有效的。只是不是两个指标之间的比较。
我也使用了内部连接和左外部连接的变体,但这些也return没有结果。
我是在比较两个无法比较的索引还是遗漏了一些语句(因为 documentation/example 有点薄)。
(当然我可以不使用光学来解决,但在这种情况下它会很合适)
[更新]
我最终通过更改最终语句使其工作:
return $subids
=> op:join-cross-product($notids)
=> op:where(op:eq(op:col('subid'), op:col('notid')))
=> op:result()
所以你不能在条件中使用片段定义。在此之后,我将 join-cross-product 替换为 join-inner 结构,这应该会更有效率。
为了完整起见,我最初使用了此处找到的 MarkLogic 文档中的示例 (https://docs.marklogic.com/guide/app-dev/OpticAPI#id_87356),特别是最后一个示例,他们使用片段列定义作为 join-inner 中的参数在我的案例中不起作用的声明。
叉积通常只对小行集有用。
将两个引用放在同一个 from-lexicons() 访问器中进行隐式连接,这意味着引擎通过为每个文档构建索引值的本地叉积来形成行。
这样的查询可以表示为:
op:from-lexicons(
map:entry("subid", cts:field-reference("id"))
=>map:with("notid", cts:element-attribute-reference(xs:QName("x"),
xs:QName("refid")))
=>op:where(cts:collection-query("latest"))
=>op:result()
显式连接可以通过以下方式完成:
let $subids := op:from-lexicons(
map:entry("subid", cts:field-reference("id")), (), $subfrag)
=> op:where($query)
let $notids := op:from-lexicons(
map:entry("notid", cts:element-attribute-reference(xs:QName("x"),
xs:QName("refid"))),
(),
$notfrag)
return $subids
=> op:join-inner($notids, op:on($notfrag, $subfrag))
=> op:result()
希望对您有所帮助,