Xquery 如何对相应的值求和?

Xquery 如何对相应的值求和?,xquery,marklogic,Xquery,Marklogic,输入xml格式: a.xml <Global> <CurrencyType>INR</CurrencyType> <Amount>100.56</Amount> </Global> b.xml <Global> <CurrencyType>USD</CurrencyType> <Amount>234.45</Amount> </Global&

输入xml格式:

a.xml
<Global>
  <CurrencyType>INR</CurrencyType>
  <Amount>100.56</Amount>
</Global>

b.xml
<Global>
  <CurrencyType>USD</CurrencyType>
  <Amount>234.45</Amount>
</Global>

c.xml
<Global>
  <CurrencyType>INR</CurrencyType>
  <Amount>20</Amount>
</Global>

d.xml
<Global>
  <CurrencyType>EUR</CurrencyType>
  <Amount>450.0</Amount>
</Global>

e.xml
<Global>
  <CurrencyType>DIR</CurrencyType>
  <Amount>100.56</Amount>
</Global>
这将产生以下输出

120.56卢比

234.45美元

450.0其他

100.0其他

现在,我需要将具有相同货币值的值相加。我需要加上450.0+100.0,即得到其他货币值的总数

有人能帮忙吗?

distinct-values()
可能是一个非常昂贵的电话

对于你的问题,你也不需要它

只需做3个查询,一个是INR,一个是USD,另一个是cts:not查询(cts:element-value查询(xs:QName('CurrencyType'),('INR',USD'))
distinct-values()
可能是一个非常昂贵的调用

对于你的问题,你也不需要它


只需执行3个查询,一个是INR,一个是USD,另一个是cts:not查询(cts:element-value查询(xs:QName('CurrencyType'),('INR',USD”)

取决于“所有XML文件”的文档数量,加载所有这些文档并将其转换为
CurrencyType
,并使用
distinct-value()
可能既昂贵又缓慢

相反,您可以:

  • 使用
    cts:element-value-co-occurrences()
    获取这些文档的
    CurrencyType
    Amount
    值的不同列表,并将结果作为映射返回
  • 迭代每个映射条目并规范化
    CurrencyType
    ,并将规范化
    CurrencyType
    标签的所有
    Amount
    值相加
  • 然后把总数打印出来


  • 根据“所有XML文件”的文档数量,加载所有这些文档并浏览到
    CurrencyType
    ,以及使用
    distinct-values()
    可能既昂贵又缓慢

    相反,您可以:

  • 使用
    cts:element-value-co-occurrences()
    获取这些文档的
    CurrencyType
    Amount
    值的不同列表,并将结果作为映射返回
  • 迭代每个映射条目并规范化
    CurrencyType
    ,并将规范化
    CurrencyType
    标签的所有
    Amount
    值相加
  • 然后把总数打印出来


  • 正如Jim和Mads所提到的,避免使用不同的值。特别是因为
    cts:element value
    无论如何都需要一个范围索引。我还避免使用
    cts:sum
    (顺便说一句,官方不推荐使用),而是使用性能更高的。我会考虑吉姆的方法,做一些类似的事情:

    let $currencies := cts:values(cts:element-reference(xs:QName("CurrencyType")))
    let $explicit-currencies := $currencies[. = ("INR", "USD")]
    let $other-currencies := $currencies[not(. = $explicit-currencies)]
    return (
      for $c in $explicit-currencies
      let $sum := cts:sum-aggregate(
        cts:element-reference(xs:QName("Amount")),
        (),
        cts:range-query(cts:element-reference(xs:QName("CurrencyType")), "=", $c)
      )
      return $c || " " || $sum,
    
      let $other-sum := cts:sum-aggregate(
        cts:element-reference(xs:QName("Amount")),
        (),
        cts:range-query(cts:element-reference(xs:QName("CurrencyType")), "=", $other-currencies)
      )
      return "OTH" || " " || $other-sum
    )
    
    注意:
    cts:range query
    在MarkLogic 9中是新的。您可以在旧版本中使用
    cts:element range query

    您可以进一步缩短上述代码,并按照Jim的建议执行:

    let $explicit-currencies := ("INR", "USD")
    return (
      for $c in $explicit-currencies
      let $sum := cts:sum-aggregate(
        cts:element-reference(xs:QName("Amount")),
        (),
        cts:range-query(cts:element-reference(xs:QName("CurrencyType")), "=", $c)
      )
      return $c || " " || $sum,
    
      let $other-sum := cts:sum-aggregate(
        cts:element-reference(xs:QName("Amount")),
        (),
        cts:not-query(cts:element-value-query(xs:QName("CurrencyType"), $explicit-currencies))
      )
      return "OTH" || " " || $other-sum
    )
    
    后者不需要在
    CurrencyType
    上使用范围索引,但是如果您将其作为facet公开,那么无论如何您都可能拥有范围索引


    如Jim和Mads所述,避免使用不同的值。特别是因为
    cts:element value
    无论如何都需要一个范围索引。我还避免使用
    cts:sum
    (顺便说一句,官方不推荐使用),而是使用性能更高的。我会考虑吉姆的方法,做一些类似的事情:

    let $currencies := cts:values(cts:element-reference(xs:QName("CurrencyType")))
    let $explicit-currencies := $currencies[. = ("INR", "USD")]
    let $other-currencies := $currencies[not(. = $explicit-currencies)]
    return (
      for $c in $explicit-currencies
      let $sum := cts:sum-aggregate(
        cts:element-reference(xs:QName("Amount")),
        (),
        cts:range-query(cts:element-reference(xs:QName("CurrencyType")), "=", $c)
      )
      return $c || " " || $sum,
    
      let $other-sum := cts:sum-aggregate(
        cts:element-reference(xs:QName("Amount")),
        (),
        cts:range-query(cts:element-reference(xs:QName("CurrencyType")), "=", $other-currencies)
      )
      return "OTH" || " " || $other-sum
    )
    
    注意:
    cts:range query
    在MarkLogic 9中是新的。您可以在旧版本中使用
    cts:element range query

    您可以进一步缩短上述代码,并按照Jim的建议执行:

    let $explicit-currencies := ("INR", "USD")
    return (
      for $c in $explicit-currencies
      let $sum := cts:sum-aggregate(
        cts:element-reference(xs:QName("Amount")),
        (),
        cts:range-query(cts:element-reference(xs:QName("CurrencyType")), "=", $c)
      )
      return $c || " " || $sum,
    
      let $other-sum := cts:sum-aggregate(
        cts:element-reference(xs:QName("Amount")),
        (),
        cts:not-query(cts:element-value-query(xs:QName("CurrencyType"), $explicit-currencies))
      )
      return "OTH" || " " || $other-sum
    )
    
    后者不需要在
    CurrencyType
    上使用范围索引,但是如果您将其作为facet公开,那么无论如何您都可能拥有范围索引


    您的确切输入格式是什么?它是单个字符串、XML数据还是完全不同的东西?输出应该是什么样子?MarkLogic 9是选项吗?如果没有,什么版本的MarkLogic?您的确切输入格式是什么?它是单个字符串、XML数据还是完全不同的东西?输出应该是什么样子?MarkLogic 9是选项吗?如果没有,什么版本的MarkLogic?