Xquery 在MarkLogic中比较同一文档的两个元素
我有一个MarkLogic 8数据库,其中有两个日期时间字段的文档:Xquery 在MarkLogic中比较同一文档的两个元素,xquery,marklogic,marklogic-8,Xquery,Marklogic,Marklogic 8,我有一个MarkLogic 8数据库,其中有两个日期时间字段的文档: 创建于 自 我正试图编写一个Xquery来搜索所有值处于活动状态的文档,因为小于上创建的值 目前我正在使用以下FLWOR表达式: fn中$entity的:集合(“entities”) let$id:=fn:data($entity//id) 让$created on:=fn:data($entity//created on) 让$active-since:=fn:data($entity//active-since) 其中$a
创建于
自
值处于活动状态的文档,因为小于上创建的值
目前我正在使用以下FLWOR表达式:
fn中$entity的:集合(“entities”)
let$id:=fn:data($entity//id)
让$created on:=fn:data($entity//created on)
让$active-since:=fn:data($entity//active-since)
其中$active,自创建日期起<$
返回
(
$id,
$创建于,
$活动自
)
上述查询执行时间过长,并且随着文档数量的增加,此查询的执行时间也将增加
还有,我有
元素范围索引
用于上述两个日期时间字段,但此处不使用它们。该函数仅将一个元素与一组原子值进行比较。在我的例子中,我试图比较同一文档的两个元素
我认为应该有一个更好的和优化的解决方案来解决这个问题
如果有任何搜索功能或任何其他方法适用于此场景,请告知我。这可能对您足够有效
获取其中一个值,并为每个值构建一个范围查询。这一切都使用范围索引,因此从这个意义上讲,它是有效的。然而,在某种程度上,我们构建了一个大型查询。它读起来和flword语句相似。如果您真的想更高效一点,您可以找出元素的唯一值(索引的大小)越小,您可以将其用于迭代,从而构建一个更小的查询。另外,您将注意到,在元素值调用中,我还将其约束到您的集合。这只是为了防止您的集合之外的文档中碰巧有该元素。这将使列表仅限于您知道的集合中的值:
let $q := cts:or-query(
for $created-on in cts:element-values(xs:QName("created-on"), (), cts:collection-query("entities"))
return cts:element-value-range-query(xs:Qname("active-since"), "<" $created-on)
)
return
cts:search(
fn:collection("entities"),
$q
)
let$q:=cts:或查询(
对于cts中的$created on:element值(xs:QName(“created on”),(),cts:collection查询(“实体”))
返回cts:element值范围查询(xs:Qname(“活动自”),“您可以尝试使用cts:tuple-values()
。传入三个引用:自
以来处于活动状态,在
上创建,以及URI引用。然后迭代结果,查找自
以来处于活动状态的小于在
上创建的的结果,您将获得文档的URI
这不是最漂亮的代码,但它会让所有数据都来自RAM,因此它应该可以很好地扩展。很抱歉没有足够的声誉,因此我需要在这里对您的答案进行评论。为什么您认为ML不会返回(2,3)和(4,2)。我相信我们使用的是Or查询,它会将任何单个查询视为true并返回文档。我现在使用以下脚本获取值处于活动状态的文档计数,因为的值小于在
上创建的的值:
fn:sum(
对于cts中的$value对:值元组(
(
cts:元素引用(xs:QName(“创建日期”),
cts:元素引用(xs:QName(“活动自”))
),
(“片段频率”),
cts:集合查询(“实体”)
)
让$created on:=json:array value($value pairs)[1]
让$active-since:=json:array-values($value-pairs)[2]
返回
如果($自上创建lt$后处于活动状态),则cts:frequency($值对)否则为0
)
谢谢@hunterhacker。使用可以更快地获得所需的结果。
let $ := cts:or-query(
for $a in cts:element-values(xs:QName("A"))
return cts:element-value-range-query(xs:Qname("B"), "<" $a)
)
cts:or-query(
(
cts:element-value-range-query(xs:Qname("B"), "<" 2),
cts:element-value-range-query(xs:Qname("B"), "<" 4),
cts:element-value-range-query(xs:Qname("B"), "<" 5)
)
)