Mule Mongo Connector生成INNER JOIN结果

时间:2015-06-14 16:23:22

标签: mongodb join mule

我有两个集合,一个组织和一个组织内的品牌,我正在尝试生成一个结果集,该结果集将与组织相关的品牌显示为组织JSON结果中的嵌套JSON。

获取结果的代码如下所示,它确实返回了预期的结果,但是最终的JSON在每个brad中都有引号。如何在不将其作为字符串包含的情况下包含品牌的JSON?

通过Mongo的Mongo ID查询单个组织:

    <mongo:find-one-object-using-query-map config-ref="mdb_config" collection="orgs" doc:name="Fetch object from Mongo">
        <mongo:query-attributes>                
            <mongo:query-attribute key="_id">#[new org.bson.types.ObjectId(flowVars.OrgId)]</mongo:query-attribute>
        </mongo:query-attributes>
    </mongo:find-one-object-using-query-map>
    <mongo:db-object-to-map doc:name="Map Mongo object to hashmap"/>

查询组织品牌列表:

                 

    <foreach collection="#[payload.brands]" doc:name="For Each" rootMessageVariableName="rootMessage">
        <mongo:find-one-object-using-query-map config-ref="mdb_config" collection="brands" doc:name="Fetch brands for org">
            <mongo:query-attributes>                
                <mongo:query-attribute key="_id">#[new org.bson.types.ObjectId(message.payload)]</mongo:query-attribute>
            </mongo:query-attributes>
        </mongo:find-one-object-using-query-map >

        <!-- Transform the brand from Mongo to JSON schema compliant JSON -->
            <scripting:transformer doc:name="Map Mongo object to JSON">
                <scripting:script engine="Groovy"><![CDATA[
                     def builder = new groovy.json.JsonBuilder()
                     def root = builder {
                         brandId payload._id.toString()
                         //...
                         isActive payload.platformHeader.isActive
                     }
                     return builder.toPrettyString();
                 ]]></scripting:script>
            </scripting:transformer>
        <expression-component>brandResponses.add(message.payloadAs(java.lang.String))
        </expression-component>
        <logger message="The result is #[message.payloadAs(java.lang.String)]"  level="INFO" doc:name="Logger"/>
    </foreach> 
    <logger level="INFO" message="#[brandResponses]"/>
            <!-- Transform the org from Mongo to JSON schema compliant JSON -->
    <scripting:transformer doc:name="Map Mongo object to JSON">
        <scripting:script engine="Groovy"><![CDATA[
           def brandsPayload = flowVars.brandResponses
            def builder = new groovy.json.JsonBuilder()
            def root = builder {
                orgId payload._id.toString()
                //...
                isActive payload.platformHeader.isActive
                brands(brandsPayload.collect {it})
            }
            return builder.toPrettyString();
        ]]></scripting:script>
    </scripting:transformer>

产生的JSON

{
    "orgId": "5565f305b85c31182a65a6a7",
    "isActive": true,
    "brands": [
        "{
        "brandId": "5565f2ff03758e0c189a753d",
        "isActive": true
        }",
        "{
        "brandId": "5565f2ff03758e0c189a7594",
        "isActive": true
        }"
    ]
}

2 个答案:

答案 0 :(得分:1)

问题来自于您在brandResponses中存储品牌的字符串表示,因此您将它们作为最终JSON中的字符串收集。

请注意,为了生成JSON,使用Groovy没有什么大的收获。使用MEL构建映射/列表并使用json:object-to-json-transformer将它们序列化为JSON对象/数组更容易(作为比较,Grooxy对于XML生成更容易)。

无论如何,要解决您的问题:

  • 删除第一个scripting:transformer
  • 将表达式组件替换为以地图而非字符串存储品牌,并使用:brandResponses.add(["brandId":payload._id.toString(), "isActive":payload.platformHeader.isActive])

我相信应该这样做。如果没有,您可能需要查看collect闭包以正确生成JSON。

答案 1 :(得分:1)

MongoDb connector (v4.2.0)的最新版本与以前的版本非常不同。每项操作Input and Output formats are different

将Document对象转换为JSON json:object-to-json-transformer

时,我遇到了类似的问题

解决方案类似:在将org.bson.Document对象转换为JSON之前将expression-component放在下面的代码中

payload.append("id",payload.getObjectId("_id").toString())

Document.append()方法返回更新的文档对象。

enter image description here

希望得到这个帮助。