Which is the proper way to work with complex types (lists and objects) in Jaspersoft?

697 Views Asked by At

Please consider a MongoDB collection with the following document:

"_id": "clientsInfo"
"data": {
    "clientsList" : [ 
        {
            "name" : "Mike",
            "country" : "USA"
        },
        ...
    ]
}

After setting the DataSet and defining the Query like this...

{
    collectionName:'projectA',
    findQuery: {
        '_id':'clientsInfo',
    },
    findFields: {
        '_id':0,
        'data.clientsList':1
    },
}

...I am able to display the first item of the fetched array (java.util.List type) in JasperSoft Studio inside a Text Field using the following expression:

$F{data.clientsList}.get(0)

But, considering that I would like to exhibit the whole data in a Name/Country Table...

Question1: How could I access any of the dictionary fields? Trying get method I obtain The method get(String) is undefined for the type Object. error. However, knowing that the object is an instance of com.mongodb.BasicDBObject it should have that method inherited (See doc).

I have also tried to cast object to org.json.JSONObject but then I get net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression for source text: (JSONObject)$F{data.clientsList}.get(0) error.

Question2: Let's suppose we have already solved first question... How can I iterate the list to access not only the first item but all of them according to the array length? Is it possible to use for-loop sentence inside the JasperSoft Expression Editor? (if-then-else seems to be available)

Thanks in advance, Any clue that point me in the right direction will be appreciated.

1

There are 1 best solutions below

0
On

Just in case someone was in the same situation as I was, I must say this whole approach was wrong.

It's not about making a simple query which returns big block of complex data formatted as an object or list of objects and then manipulate it with JasperSoft Studio. Instead, what I had to do was design a more elaborated query which returns the simple fields I wanted to use straightforward. How to do this? By using Aggregation Framework.

So, by changing this...

{
    collectionName:'projectA',
    findQuery: {
        '_id':'clientsInfo',
    },
    findFields: {
        '_id':0,
        'data.clientsList':1
    },
}

...for this...

{
    runCommand: {
    aggregate : 'projectA',
    pipeline : [
        {'$match': {'_id':'clientsInfo'}},
        {'$project': {'data.clientsList': 1}},
        {'$unwind': '$data'},
        {'$unwind': '$data.clientsList'}
        ]
    }
}

...is how I get name and country fields in order to use them in Text Fields, Tables, ...etc.