Xquery 在MarkLogic中比较同一文档的两个元素

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

我有一个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)
    其中$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)
        )
     )