I am using Excel Powerquery (M Language) to access the RESTful API of a SNOMED CT server. The JSON returned by the server is a deeply nested structure.
The example below is filtered to show a single item, normally the items array will contain multiple results.
Example-
{
"items": [
{
"id": "258674000",
"released": true,
"active": true,
"effectiveTime": "20020131",
"moduleId": "900000000000207008",
"iconId": "362981000",
"definitionStatus": {
"id": "900000000000074008"
},
"subclassDefinitionStatus": "NON_DISJOINT_SUBCLASSES",
"fsn": {
"id": "3508354011",
"term": "Micrometer (qualifier value)",
"concept": {
"id": "258674000"
},
"type": {
"id": "900000000000003001"
},
"typeId": "900000000000003001",
"conceptId": "258674000",
"acceptability": {
"900000000000509007": "PREFERRED",
"900000000000508004": "PREFERRED"
}
},
"pt": {
"id": "384891018",
"term": "um",
"concept": {
"id": "258674000"
},
"type": {
"id": "900000000000013009"
},
"typeId": "900000000000013009",
"conceptId": "258674000",
"acceptability": {
"900000000000509007": "PREFERRED",
"900000000000508004": "PREFERRED"
}
},
"descriptions": {
"items": [
{
"id": "2609609012",
"released": true,
"active": false,
"effectiveTime": "20170731",
"moduleId": "900000000000207008",
"iconId": "900000000000003001",
"term": "micrometer (qualifier value)",
"semanticTag": "qualifier value",
"languageCode": "en",
"caseSignificance": {
"id": "900000000000448009"
},
"concept": {
"id": "258674000"
},
"type": {
"id": "900000000000003001"
},
"typeId": "900000000000003001",
"conceptId": "258674000",
"caseSignificanceId": "900000000000448009",
"acceptability": {}
},
{
"id": "384891018",
"released": true,
"active": true,
"effectiveTime": "20020131",
"moduleId": "900000000000207008",
"iconId": "900000000000013009",
"term": "um",
"semanticTag": "",
"languageCode": "en",
"caseSignificance": {
"id": "900000000000017005"
},
"concept": {
"id": "258674000"
},
"type": {
"id": "900000000000013009"
},
"typeId": "900000000000013009",
"conceptId": "258674000",
"caseSignificanceId": "900000000000017005",
"acceptability": {
"900000000000509007": "PREFERRED",
"900000000000508004": "PREFERRED"
}
},
{
"id": "650119013",
"released": true,
"active": false,
"effectiveTime": "20060731",
"moduleId": "900000000000207008",
"iconId": "900000000000003001",
"term": "um (qualifier value)",
"semanticTag": "qualifier value",
"languageCode": "en",
"caseSignificance": {
"id": "900000000000017005"
},
"concept": {
"id": "258674000"
},
"type": {
"id": "900000000000003001"
},
"typeId": "900000000000003001",
"conceptId": "258674000",
"caseSignificanceId": "900000000000017005",
"acceptability": {}
},
{
"id": "384888018",
"released": true,
"active": false,
"effectiveTime": "20170731",
"moduleId": "900000000000207008",
"iconId": "900000000000013009",
"term": "micrometer",
"semanticTag": "",
"languageCode": "en",
"caseSignificance": {
"id": "900000000000448009"
},
"concept": {
"id": "258674000"
},
"type": {
"id": "900000000000013009"
},
"typeId": "900000000000013009",
"conceptId": "258674000",
"caseSignificanceId": "900000000000448009",
"acceptability": {}
},
{
"id": "3508354011",
"released": true,
"active": true,
"effectiveTime": "20170731",
"moduleId": "900000000000207008",
"iconId": "900000000000003001",
"term": "Micrometer (qualifier value)",
"semanticTag": "qualifier value",
"languageCode": "en",
"caseSignificance": {
"id": "900000000000448009"
},
"concept": {
"id": "258674000"
},
"type": {
"id": "900000000000003001"
},
"typeId": "900000000000003001",
"conceptId": "258674000",
"caseSignificanceId": "900000000000448009",
"acceptability": {
"900000000000509007": "PREFERRED",
"900000000000508004": "PREFERRED"
}
},
{
"id": "3508411019",
"released": true,
"active": true,
"effectiveTime": "20170731",
"moduleId": "900000000000207008",
"iconId": "900000000000013009",
"term": "Micrometer",
"semanticTag": "",
"languageCode": "en",
"caseSignificance": {
"id": "900000000000448009"
},
"concept": {
"id": "258674000"
},
"type": {
"id": "900000000000013009"
},
"typeId": "900000000000013009",
"conceptId": "258674000",
"caseSignificanceId": "900000000000448009",
"acceptability": {
"900000000000509007": "ACCEPTABLE"
}
},
{
"id": "384889014",
"released": true,
"active": true,
"effectiveTime": "20020131",
"moduleId": "900000000000207008",
"iconId": "900000000000013009",
"term": "micrometre",
"semanticTag": "",
"languageCode": "en",
"caseSignificance": {
"id": "900000000000017005"
},
"concept": {
"id": "258674000"
},
"type": {
"id": "900000000000013009"
},
"typeId": "900000000000013009",
"conceptId": "258674000",
"caseSignificanceId": "900000000000017005",
"acceptability": {
"900000000000508004": "ACCEPTABLE"
}
},
{
"id": "384890017",
"released": true,
"active": true,
"effectiveTime": "20020131",
"moduleId": "900000000000207008",
"iconId": "900000000000013009",
"term": "micron",
"semanticTag": "",
"languageCode": "en",
"caseSignificance": {
"id": "900000000000017005"
},
"concept": {
"id": "258674000"
},
"type": {
"id": "900000000000013009"
},
"typeId": "900000000000013009",
"conceptId": "258674000",
"caseSignificanceId": "900000000000017005",
"acceptability": {
"900000000000509007": "ACCEPTABLE",
"900000000000508004": "ACCEPTABLE"
}
}
],
"limit": 8,
"total": 8
},
"ancestorIds": [
"-1",
"138875005",
"258667005",
"362981000",
"767524001"
],
"parentIds": [
"258668000"
],
"statedAncestorIds": [
"-1",
"138875005",
"258667005",
"362981000",
"767524001"
],
"statedParentIds": [
"258668000"
],
"definitionStatusId": "900000000000074008"
}
],
"searchAfter": "AoE_BTAxMzRlZWNhLTYxODEtNDFjYi1hNmJlLWQzN2IwMGFlYzEyNA==",
"limit": 50,
"total": 1
}
The top level object in the JSON represents a List of Records in M language terms. Using a custom function fromServer(endpoint)
that queries the server I was able to expand the JSON result using-
let
concepts = Table.FromRecords(fromServer("API_ENDPOINT")[items]),
in
concepts
This gives me a table of concepts, one per line. However i'm stuck at the next point.
Each concept has a set of possible synonyms. These are descriptions in SNOMED terms. The descriptions
column in the table described above is a column of Records, where each Record has a field items
. items
is a list of Records, and the Records contain the key/value pairs to access. What I want to do is expand the descriptions
column, unrolling either selected values by name, or all values from the bottom level Records.
So, that is something like a Table.ExpandTableColumn()
where the values to be expanded come from a column of shape-
descriptions (the column name)
Records
items: List
Records
Keys : Values
I must admit i'm not sure how to get started on this, marching down into a nested structured value in a table field and then accumulating the results. Any pointers would be appreciated.