Как l oop и объединить как одно в Mule Dataweave - PullRequest
1 голос
/ 26 мая 2020

У меня есть запрос json и ожидаемый ответ, как указано ниже. Это нужно сгруппировать по clientItemCode, и я где-то на полпути застрял в l oop примерно так же. Используется как комбинация функций MapObject, так и reduce. Любая помощь будет принята с благодарностью.

[
{
  "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>

Ответы [ 2 ]

2 голосов
/ 27 мая 2020

Это то, что я придумал, возможно, это можно было бы немного упростить, если бы у меня было больше времени на это. Попробуйте:

%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})
                    }
                }
            }
        }}
    }
}

Я также сделал предположение, повторяя в комментариях: я предполагаю, что ваши данные упорядочены и все записи, которые будут From и To, связаны с друг друга.

РЕДАКТИРОВАТЬ: Еще раз отредактировал код, чтобы принудительно выполнить сортировку ClientItemCode, а затем получить доступ к каждому из значений по порядку перед всеми преобразованиями при создании тегов result. Остальной код почти такой же, как и раньше. Не уверен, почему простой orderBy не сработал для вас, он сработал для меня.

2 голосов
/ 26 мая 2020

Предполагая, что ОТКРЫТО и / или ЗАКРЫТО могло отсутствовать:

%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>
...