【问题标题】:How to loop and combine as one in Mule Dataweave如何在 Mule Dataweave 中循环和合并
【发布时间】:2020-09-13 05:29:46
【问题描述】:

我有如下所述的 json 请求和预期的响应之一。它需要 groupBy clientItemCode 并且我在某个地方被困在同一处循环。使用MapObjectreduce 组合功能。任何帮助将不胜感激。

[
{
  "ClientCode": "1",
  "ClientItemCode": "245",
  "LocationId": "CLOSED"
 },
 {
  "ClientCode": "1",
  "ClientItemCode": "245",
  "LocationId": "OPEN"
 },
    {
  "ClientCode": "2",
  "ClientItemCode": "245",
  "LocationId": "CHECKOUT"
 },
 {
  "ClientCode": "2",
  "ClientItemCode": "245",
  "LocationId": "TEST"
 },
 {
  "ClientCode": "1",
  "ClientItemCode": "123",
  "LocationId": "OPEN"
 },
 {
  "ClientCode": "1",
  "ClientItemCode": "123",
  "LocationId": "CLOSED"
 }
 ]

预期响应:

  <Results>
  <Result>
    <ClientItemCode>123<ClientItemCode>
    <ResultLines>
      <ResultLine>
        <ClientCode>1</ClientCode>
        <From>
          <LocationId>OPEN</LocationId>
        </From>
        <To>
          <LocationId>CLOSED</LocationId>
        </To>
      </ResultLine>
       <ResultLine>
        <ClientCode>2</ClientCode>
        <From>
          <LocationId>CHECKOUT</LocationId>
        </From>
        <To>
          <LocationId>TEST</LocationId>
        </To>
      </ResultLine>
    </ResultLines>
  </Result>
  <Result>
   <CientItemCode>245<ClientItemCode>
   <ResultLines>
      <ResultLine>
        <ClientCode>1</ClientCode>
        <From>
          <LocationId>CLOSED</LocationId>
        </From>
        <To>
          <LocationId>OPEN</LocationId>
        </To>
     </ResultLine>
    </ResultLines>
  </Result>
</Results>

【问题讨论】:

  • 我认为您的输出数据有误:您将245123 ClientItemCode 混淆了

标签: mule dataweave mule4


【解决方案1】:

这是我想出的,如果我有更多的时间投入,可能会简化一点。试试看:

%dw 2.0
output application/xml
var data = [
 {
  "ClientCode": "1",
  "ClientItemCode": "245",
  "LocationId": "CLOSED"
 },
 {
  "ClientCode": "1",
  "ClientItemCode": "245",
  "LocationId": "OPEN"
 },
    {
  "ClientCode": "2",
  "ClientItemCode": "245",
  "LocationId": "CHECKOUT"
 },
 {
  "ClientCode": "2",
  "ClientItemCode": "245",
  "LocationId": "TEST"
 },
 {
  "ClientCode": "1",
  "ClientItemCode": "123",
  "LocationId": "OPEN"
 },
 {
  "ClientCode": "1",
  "ClientItemCode": "123",
  "LocationId": "CLOSED"
 }
]
---
// I assume that your data are ordered and all the records that will be From and To
// are paired with one another. It is doable without making such assumption but the
// algorithm will get complex.
results: do {
    // Group by the data
    var groupedData = data map {($),(From: true) if (isEven($$))} groupBy $.ClientItemCode
    // Order the client Ids
    var orderedClientIds = groupedData pluck $$ orderBy $ as Number
    ---
    orderedClientIds reduce (cId, results={}) -> do {
        var clientItemCode = cId
        var groupedByClientICode = groupedData[cId] groupBy $.ClientCode pluck $
        ---
        results ++ {result: {
            ClientItemCode: clientItemCode,
            ResultLines: groupedByClientICode reduce (cliCode, lines={}) -> do {
                var clientCode = cliCode[0].ClientCode
                ---
                lines ++ {
                    ClientCode: clientCode,
                    ResultLine: cliCode reduce (e, acc={}) -> do {
                        var locRec = {LocationId: e.LocationId}
                        ---
                        acc ++ (if (e.From?) {From: locRec } else {To: locRec})
                    }
                }
            }
        }}
    }
}

当我在 cmets 中复制时,我还做了一个假设:我假设您的数据是有序的,并且所有将是 FromTo 的记录都相互配对。

编辑:再次编辑代码以强制对ClientItemCode 进行排序,然后在创建result 标记的所有转换之前按顺序访问每个值。其余的代码几乎和以前一样。不知道为什么一个简单的orderBy 对你不起作用,它对我起作用。

【讨论】:

  • 太棒了!!感谢您在急需的时间提供快速帮助。它按预期工作。
  • 在上面的代码中,orderBy ClientItemCode 缺失,正如您在上面的响应中看到的那样,它是有序的。抱歉,我错过了措辞。我尝试添加orderBy $.ClientItemCode groupBy $.ClientItemCode 看起来不起作用。你有什么想法吗???
  • 哦,您仍然希望他们订购 :)。可以通过与此类似的方式完成:stackoverflow.com/questions/61836535/…。我会在今天晚些时候的某个时间解决它。
  • 感谢您的回复。确实,我按照上面链接中的说明进行了尝试,因为它大多相似,尽管它没有在 dataweave 中引发错误,orderBy 的功能不起作用。不知道我在哪里失踪。等待您的回复。
  • 我刚刚编辑了代码以包含基于ClientItemCodeorderBy,试试吧
【解决方案2】:

假设可能缺少 OPEN 和/或 CLOSED:

%dw 2.0
output application/xml
---
Results: payload groupBy $.ClientItemCode
    mapObject ((value, key, index) -> result: {
            ClientItemCode: key,
            ResultLines: {
                From: if (value.LocationId contains "OPEN") LocationId: "OPEN" else null,
                To: if (value.LocationId contains "CLOSED") LocationId: "CLOSED" else null

            }
        } 
    )

输出:

<?xml version='1.0' encoding='UTF-8'?>
<Results>
  <result>
    <ClientItemCode>245</ClientItemCode>
    <ResultLines>
      <From>
        <LocationId>OPEN</LocationId>
      </From>
      <To>
        <LocationId>CLOSED</LocationId>
      </To>
    </ResultLines>
  </result>
  <result>
    <ClientItemCode>123</ClientItemCode>
    <ResultLines>
      <From>
        <LocationId>OPEN</LocationId>
      </From>
      <To>
        <LocationId>CLOSED</LocationId>
      </To>
    </ResultLines>
  </result>
</Results>

【讨论】:

  • 感谢您的回复。但我需要它动态,因为而不是close 或'open',它们可能会出现其他一些值,而不是contains 在数组中查找所有并在匹配时将其放在那里。我相应地更新了我的问题以获得清晰的图片。请多多取舍。非常感谢
  • 每个 ClientItemCode 是否总是有 2 条记录?他们会被订购吗?
  • 超过 2 条记录,是的,预计将被订购。感谢您的双重检查。亲爱的你。
  • 我更新了我的请求,希望你能清楚,我不想变得复杂,所以在我的原始帖子中缩短了它。但是,是的,我正在寻找上述回复。 ClientItemCodeclientCode 有 orderBy 发生。它与这篇文章 stackoverflow.com/questions/61836535/… 非常相似,但里面的逻辑不同,我很难理解。
  • 我不清楚我的问题。我的意思是问是否总是有一个 from 和一个 to 位置,这些是每个 clientitemcode 的 2 条记录。从示例中看起来是这样,但我想确定。
猜你喜欢
  • 2016-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
相关资源
最近更新 更多