When a list of results are returned, the URL ends in a / and the HTTP method is a GET, as is typical of REST design. In that case, Indivo X supports a generic query string that determines paging and ordering of the results:
?offset={offset}&limit={limit}&order_by={order_by}&status={document_status}
For minimal (url ends in /reports/minimal/{report_type}/) and generic reports, we expose an expanded query interface, allowing for filtering, date constraints, and aggregation. Note that this interface only makes sense to implement for reports that function solely to retrieve and display fact objects. The interface will not be implemented for any more complex report types that deal with multiple fact objects (what would it mean for a CCR report to group by lab type?). Other reports will still have access to the Beta2-style paging operations. The interface will be available for other API calls to implement as well (i.e. the Audit interface)
In the previous interface, reports were templated into schemas for output as specified by the Indivo Reporting Schema. This output method will be preserved for queries that return sets of fact objects, but for queries that return aggregates or groups, we will output data according to the Indivo Aggregate Report Schema.
XML
Formatted according to the Indivo Generic Aggregate Reports Schema
JSON
Formatted as SDMJ with AggregateReport as the data model and without a __documentid__. Below is an example of retrieving the max value using the date_group operator
[ { "__modelname__": "AggregateReport", "group": "2009-07", "value": 1 }, { "__modelname__": "AggregateReport", "group": "2009-08", "value": 4 } ]
As in order_by in the Beta2 interface, each report must expose a set of data fields on which they may be filtered, grouped, or ordered. These fields are data-model dependent, and are explained below.
order_by: Syntax is ?order_by={field}. Functions as previously. Takes a data field exposed by the desired report type, and returns the result set sorted by that field. Fields are sorted in ascending order by default, and prefixing them with a ‘-‘ will reverse the order to descending.
Note: If order_by is used with a grouping, {field} may only refer to the field used with group_by, date_group, or aggregate_by.
Note: Calls using grouping and aggregating operators will return data according to the aggregation schema, not the standard query schema
date_range: Syntax is ?date_range={field}*{start_date}*{end_date}. A filtering operation that limits result sets to items with values of {field} between {start_date} and {end_date} (inclusive). If either {start_date} or {end_date} is not specified, the range will be open-ended. If both are unspecified, the filter will do nothing. {field} must be a data field exposed by the desired report type. If field is not a date/time field, a 400 Bad Request error will be raised. {start_date} and {end_date} must be entered as valid UTC timestamp strings, as described in Basic Data Formats. See below for examples.
date_group: Syntax is: ?date_group={field}*{time_increment}. A grouping operator that, rather than grouping by a single field value, forms groups based on common increments of time. Has same restraints of use as group_by above, with the additional constraint that {field} must be a date/time data field.
If used with order_by, the ordering field must be identical to the grouping field or the field passed in aggregate_by.
Note: using this operator will result in the return of an aggregation schema.
Valid increments are:
Query operators are evaluated as follows:
Aggregation over Indivo medical data types could be very useful in certain cases where the data is known (by an app-developer, who generated the data, say) to be highly structured. For example, consider a ‘Pedometer-Visualizer’ app, which reads in data from an electric pedometer worn by a patient, stores that data as Indivo Measurements, and displays to the patient aggregate views of their steps taken (weekly/daily averages, total miles walked, etc.). This app could take full advantage of aggregation functions such as ‘sum’, ‘avg’, etc. However, there are many cases in Indivo where the data, in spite of conforming to Indivo schemas, is not necessarily clean enough to run these aggregations. Consider the case of lab test results: the schema field is by necessity a string, as not all lab results have numerical values. Thus, an incoming query might assume that it could ask for an ‘average lab result value’, when in fact the data wouldn’t support it. We therefore cannot allow numerical aggregations over fields not explicitly labeled as ‘Number’ types. If such a case is necessary for the app, the appropriate design is for the app to make a non-aggregate query, and then process the results itself (i.e., get all lab result values, and then do some data cleaning to insure that only relevant data points are counted in the averaging).
If omitted, the following query operators are assigned default values:
With the new pluggable data models, valid query fields are defined by the data models themselves. See the Data Models documentation for a more complete explanation.
Below are a number of sample queries that demonstrate the power of the new interface.
GET /records/{record_id}/reports/minimal/labs/?lab_type=Hematology&
date_range=date_measured*2009-05-04T00:00:00Z*2011-03-09T00:00:00Z
GET /records/{record_id}/reports/minimal/labs/?lab_type=Hematology|Chemistry
GET /records/{record_id}/reports/minimal/labs/?group_by=lab_type&
aggregate_by=count*lab_test_name&date_range=date_measured*2010-03-10T00:00:00Z*
GET /records/{record_id}/reports/minimal/labs/?lab_type=Hematology&
date_group=date_measured*month&aggregate_by=count*lab_type&
order_by=-date_measured&date_range=date_measured*2010-03-10T00:00:00Z*