working aggregation code

This commit is contained in:
Jason Kulatunga 2023-08-14 17:11:04 -06:00
parent 6f56fa9c3b
commit b3a173df01
5 changed files with 31 additions and 32 deletions

View File

@ -21,7 +21,7 @@ type DatabaseRepository interface {
GetResourceByResourceTypeAndId(context.Context, string, string) (*models.ResourceBase, error)
GetResourceBySourceId(context.Context, string, string) (*models.ResourceBase, error)
QueryResources(ctx context.Context, query models.QueryResource) ([]models.ResourceBase, error)
QueryResources(ctx context.Context, query models.QueryResource) (interface{}, error)
ListResources(context.Context, models.ListResourceQueryOptions) ([]models.ResourceBase, error)
GetPatientForSources(ctx context.Context) ([]models.ResourceBase, error)
AddResourceAssociation(ctx context.Context, source *models.SourceCredential, resourceType string, resourceId string, relatedSource *models.SourceCredential, relatedResourceType string, relatedResourceId string) error

View File

@ -47,16 +47,24 @@ const TABLE_ALIAS = "fhir"
// )
// AND (user_id = "6efcd7c5-3f29-4f0d-926d-a66ff68bbfc2")
// GROUP BY `fhir`.`id`
func (sr *SqliteRepository) QueryResources(ctx context.Context, query models.QueryResource) ([]models.ResourceBase, error) {
results := []models.ResourceBase{}
func (sr *SqliteRepository) QueryResources(ctx context.Context, query models.QueryResource) (interface{}, error) {
sqlQuery, err := sr.sqlQueryResources(ctx, query)
if err != nil {
return nil, err
}
clientResp := sqlQuery.Find(&results)
return results, clientResp.Error
if query.Aggregations != nil && (len(query.Aggregations.GroupBy) > 0 || len(query.Aggregations.CountBy) > 0) {
results := []map[string]interface{}{}
clientResp := sqlQuery.Find(&results)
return results, clientResp.Error
} else {
results := []models.ResourceBase{}
clientResp := sqlQuery.Find(&results)
return results, clientResp.Error
}
}
// see QueryResources
@ -181,8 +189,8 @@ func (sr *SqliteRepository) sqlQueryResources(ctx context.Context, query models.
groupClause = AggregationParameterToClause(groupAggregationParam)
selectClauses = []string{
fmt.Sprintf("%s as %s", groupClause, "group_by"),
"count(*) as count",
fmt.Sprintf("%s as %s", groupClause, "label"),
"count(*) as value",
}
}
}

View File

@ -243,7 +243,7 @@ func (suite *RepositorySqlTestSuite) TestQueryResources_SQL_WithPrimitiveCountBy
require.NoError(suite.T(), err)
require.Equal(suite.T(),
strings.Join([]string{
"SELECT fhir.sourceUri as group_by, count(*) as count",
"SELECT fhir.sourceUri as label, count(*) as value",
"FROM fhir_observation as fhir, json_each(fhir.code) as codeJson",
"WHERE ((codeJson.value ->> '$.code' = ?)) AND (user_id = ?)",
"GROUP BY `fhir`.`sourceUri`",
@ -280,7 +280,7 @@ func (suite *RepositorySqlTestSuite) TestQueryResources_SQL_WithComplexCountByAg
require.NoError(suite.T(), err)
require.Equal(suite.T(),
strings.Join([]string{
"SELECT (codeJson.value ->> '$.code') as group_by, count(*) as count",
"SELECT (codeJson.value ->> '$.code') as label, count(*) as value",
"FROM fhir_observation as fhir, json_each(fhir.code) as codeJson",
"WHERE ((codeJson.value ->> '$.code' = ?)) AND (user_id = ?)",
"GROUP BY (codeJson.value ->> '$.code')",

View File

@ -119,7 +119,7 @@
"item_type": "patient-vitals-widget"
},
{
"title_text": "Records by Type",
"title_text": "Observations by Type",
"description_text": "",
"x": 4,
"y": 5,
@ -129,15 +129,15 @@
"queries": [{
"q": {
"select": [],
"from": "",
"from": "Observation",
"where": {},
"aggregation_params":["resourceType"],
"aggregation_type":"countBy"
"aggregations":{
"count_by": "code:code"
}
}
}],
"parsing": {
"label": "key",
"label": "label",
"key": "value"
}
},

View File

@ -133,28 +133,19 @@ export class DashboardWidgetComponent implements OnInit, DashboardWidgetComponen
return []
}
let results = response.data
.map((resource: ResourceFhir) => {
if(query.aggregations?.count_by || query.aggregations?.group_by){
//list of aggregated results [{"label": "xxx", "value":"xxx"}]
return results
}
else {
//list of FHIR resources
return results.map((resource: ResourceFhir) => {
if (!resource.resource_raw) {
return null
}
return this.fhirPathMapQueryFn(query)(resource.resource_raw)
})
if(query.aggregation_type){
switch (query.aggregation_type) {
case "countBy":
return Object.entries(_[query.aggregation_type](results, ...(query.aggregation_params || []))).map(pair => {
return {key: pair[0], value: pair[1]}
})
break;
default:
throw new Error("unsupported aggregation type")
}
}
else {
return results
}
}