@mksrom - “mappings” is both a fundamentally important concept, and also one of the biggest complexities/confusions to fully understand the reporting module.
Mappings allow you to indicate how the parameter value of a parent definition should “map” to a parameter value of a child definition.
For example, let’s say you have a report and you want to be able to limit this report to patients in a certain age range.
First thing you would do is construct a new ReportDefinition that can take in the age range that you wish to limit the report to:
ReportDefinition rd = new ReportDefinition();
ageCd.addParameter(new Parameter("fromAge", "From Age", Integer.class));
ageCd.addParameter(new Parameter("toAge", "To Age", Integer.class));
Now, to limit this report, we can use an AgeCohortDefinition and set it as the “baseCohort” on the ReportDefinition. Perhaps we find that we had previously created such a definition, and it was defined as such:
AgeCohortDefinition ageCd = new AgeCohortDefinition();
ageCd.addParameter(new Parameter("minAge", "Min Age", Integer.class));
ageCd.addParameter(new Parameter("maxAge", "Max Age", Integer.class));
Now, we can’t simply add this CohortDefinition to the report. First off, it is not obvious how “fromAge” and “toAge” should relate to “minAge” and “maxAge”. To solve this, as you can see, the “baseCohort” property is not of type “CohortDefinition”. It is of type “Mapped”. This is because we need to be able to indicate how the “fromAge” and “toAge” parameter values we define on the ReportDefinition map to the “minAge” and “maxAge” parameters we have defined on the CohortDefinition.
We do this by creating a Mapped like such (in long form):
Mapped<CohortDefinition> mappedCd = new Mapped<CohortDefinition>();
mappedCd.setParameterizable(ageCd);
Map<String, Object> parameterMappings = new HashMap<String, Object>();
parameterMappings.put("minAge", "${fromAge}");
parameterMappings.put("maxAge", "${toAge}");
mappedCd.setParameterMappings(parameterMappings);
As you can see, we indicate that parameter values should pass through from parent to child definitions by mapping the parameter names.
There are various convenience methods around for reducing the amount of boilerplate code one needs to write for this, which includes what you refer to above (although this is even more obscure since it is converting to a Map<String, Object> which is then converted to a String representation of this, which will then be re-converted back to a Map in the method it is used in).
Commonly, the parent and child definitions have the same parameter names (eg. startDate, endDate, location, etc). When this is the case, the “straightThroughMappings” methods are a particularly useful convenience, including Mapped.mapStraightThrough(definition).
It should also be noted that mappings are not just limited to 1:1 parameter transfer. They also enable Mapping static values through. For example, in the above, if we always wanted to limit the report to patients between the age of 10-20, we could remove the Parameters from the ReportDefinition altogether, and change the parameterMappings to be:
parameterMappings.put("minAge", 10);
parameterMappings.put("maxAge", 20);
Mappings can also take in a limited range of expressions. The most typical use case for this is in date manipulation. For example, one could include the same DataSetDefinition that gets information about a particular date (eg. encounters on day), and include several of these in a single report. Something like:
rd.addDataSetDefinition("today", Mapped.map(encountersInPeriod, "startDate=${start_of_today},endDate=${end_of_today}"));
rd.addDataSetDefinition("yesterday", Mapped.map(encountersInPeriod, "startDate=${start_of_today-1d},endDate=${end_of_today-1d}"));
(start_of_today, and end_of_today are among a few pre-defined parameters that are always available. See here)
You can get a sense of what is possible by looking through this unit test.
Let me know if this is helpful.
Mike