从 for-each 循环聚合数据
Aggregate data from for-each loop
场景 - 将 csv 文件转换为 json 格式,获取每个 json 元素并发出获取请求 api 调用。我在 for-each 循环序列中执行此操作。我收到 json 响应(从每个响应中提取 eventId 和成本)。现在,我希望将所有这些响应集中在主要 header 列表下,并制作更大的 json 有效负载。
例如:
{
"listings": [
{
"eventId":"8993478",
"cost":34
},
{
"eventId":"xxxxxyyyy",
"cost":zz
},
]
}
我将如何为所有迭代条目执行此操作。我可以为单个条目执行此操作(使用 groovy 脚本)。
您可以在 for-each
循环之前将变量定义为空列表:
<set-variable variableName="listings" value="#[[]]" />
然后,在 for-each
循环中的每次迭代中,将一个元素添加到前一个变量中:
<expression-transformer expression="#[flowVars.listings.add(flowVars.iterationMap)]" />
在前面的代码片段中,我使用变量 flowVars.iterationMap
来表示每次迭代生成的地图。
最后,如果需要,您可以在 for-each
循环之后添加一个 set-payload
转换器:
<set-payload value="#[flowVars.listings]" />
HTH,马科斯
您可以使用 Batch 模块,但您必须稍微不同地重写此逻辑。例如,您将无法再像 Marcos 建议的那样使用聚合 flowVar。相反,您需要使用固定大小的 batch:commit 块(这在很多方面实际上会更好,例如,您可以开始向远程 API 发送批量数据,同时仍在处理中的其他一些记录的背景)。
...我喜欢 Marco 的回答,它非常适合我的用例。
只需在流变量中创建一个数组并在 ForEach 作用域中对该数组使用 add() 方法就可以了。
OP 的跟进问题很好。它促使我使用建议的方法进行替代测试。在这里查看我的两个流程:
<flow name="sampleAggregatorFlow" doc:description="this is a simple demo that shows how to aggregate results into an accumulator array">
<http:listener config-ref="manage-s3-api-httpListenerConfig" path="/aggregate" allowedMethods="GET" doc:name="HTTP"/>
<set-payload value="#[['red','blue','gold']]" doc:name="Set Payload"/>
<set-variable variableName="accumulator" value="#[[]]" doc:name="accumulator"/>
<foreach doc:name="For Each">
<expression-transformer expression="#[flowVars.accumulator.add(payload)]" doc:name="addEm"/>
</foreach>
<set-payload value="#[flowVars.accumulator]" doc:name="Set Payload"/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
</flow>
<flow name="Copy_of_sampleAggregatorFlow" doc:description="this is a simple demo that shows how to aggregate results into an accumulator array">
<http:listener config-ref="manage-s3-api-httpListenerConfig" path="/aggregate2" allowedMethods="GET" doc:name="Copy_of_HTTP"/>
<set-payload value="#[['red','blue','gold']]" doc:name="Copy_of_Set Payload"/>
<set-variable variableName="accumulator" value="#[new java.util.ArrayList()]" doc:name="Copy_of_accumulator"/>
<foreach doc:name="Copy_of_For Each">
<expression-transformer expression="#[flowVars.accumulator.add(payload)]" doc:name="Copy_of_addEm"/>
</foreach>
<set-payload value="#[flowVars.accumulator]" doc:name="Copy_of_Set Payload"/>
<json:object-to-json-transformer doc:name="Copy_of_Object to JSON"/>
</flow>
两个流产生相同的结果:
[
"red",
"blue",
"gold"
]
2017 年 12 月 26 日使用 Anypoint Studio 6.4.1 和 Mule Runtime 3.9 进行的测试
场景 - 将 csv 文件转换为 json 格式,获取每个 json 元素并发出获取请求 api 调用。我在 for-each 循环序列中执行此操作。我收到 json 响应(从每个响应中提取 eventId 和成本)。现在,我希望将所有这些响应集中在主要 header 列表下,并制作更大的 json 有效负载。
例如:
{
"listings": [
{
"eventId":"8993478",
"cost":34
},
{
"eventId":"xxxxxyyyy",
"cost":zz
},
]
}
我将如何为所有迭代条目执行此操作。我可以为单个条目执行此操作(使用 groovy 脚本)。
您可以在 for-each
循环之前将变量定义为空列表:
<set-variable variableName="listings" value="#[[]]" />
然后,在 for-each
循环中的每次迭代中,将一个元素添加到前一个变量中:
<expression-transformer expression="#[flowVars.listings.add(flowVars.iterationMap)]" />
在前面的代码片段中,我使用变量 flowVars.iterationMap
来表示每次迭代生成的地图。
最后,如果需要,您可以在 for-each
循环之后添加一个 set-payload
转换器:
<set-payload value="#[flowVars.listings]" />
HTH,马科斯
您可以使用 Batch 模块,但您必须稍微不同地重写此逻辑。例如,您将无法再像 Marcos 建议的那样使用聚合 flowVar。相反,您需要使用固定大小的 batch:commit 块(这在很多方面实际上会更好,例如,您可以开始向远程 API 发送批量数据,同时仍在处理中的其他一些记录的背景)。
...我喜欢 Marco 的回答,它非常适合我的用例。
只需在流变量中创建一个数组并在 ForEach 作用域中对该数组使用 add() 方法就可以了。
OP 的跟进问题很好。它促使我使用建议的方法进行替代测试。在这里查看我的两个流程:
<flow name="sampleAggregatorFlow" doc:description="this is a simple demo that shows how to aggregate results into an accumulator array">
<http:listener config-ref="manage-s3-api-httpListenerConfig" path="/aggregate" allowedMethods="GET" doc:name="HTTP"/>
<set-payload value="#[['red','blue','gold']]" doc:name="Set Payload"/>
<set-variable variableName="accumulator" value="#[[]]" doc:name="accumulator"/>
<foreach doc:name="For Each">
<expression-transformer expression="#[flowVars.accumulator.add(payload)]" doc:name="addEm"/>
</foreach>
<set-payload value="#[flowVars.accumulator]" doc:name="Set Payload"/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
</flow>
<flow name="Copy_of_sampleAggregatorFlow" doc:description="this is a simple demo that shows how to aggregate results into an accumulator array">
<http:listener config-ref="manage-s3-api-httpListenerConfig" path="/aggregate2" allowedMethods="GET" doc:name="Copy_of_HTTP"/>
<set-payload value="#[['red','blue','gold']]" doc:name="Copy_of_Set Payload"/>
<set-variable variableName="accumulator" value="#[new java.util.ArrayList()]" doc:name="Copy_of_accumulator"/>
<foreach doc:name="Copy_of_For Each">
<expression-transformer expression="#[flowVars.accumulator.add(payload)]" doc:name="Copy_of_addEm"/>
</foreach>
<set-payload value="#[flowVars.accumulator]" doc:name="Copy_of_Set Payload"/>
<json:object-to-json-transformer doc:name="Copy_of_Object to JSON"/>
</flow>
两个流产生相同的结果:
[
"red",
"blue",
"gold"
]
2017 年 12 月 26 日使用 Anypoint Studio 6.4.1 和 Mule Runtime 3.9 进行的测试