问题描述
我正在使用Excel Powerquery(M语言)来访问SNOMED CT服务器的RESTful API。服务器返回的JSON是一个深层嵌套的结构。
下面的示例被过滤以显示单个项目,通常items数组将包含多个结果。
示例-
{
"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","type": {
"id": "900000000000013009"
},"typeId": "900000000000013009","descriptions": {
"items": [
{
"id": "2609609012","active": false,"effectiveTime": "20170731","iconId": "900000000000003001","term": "micrometer (qualifier value)","semanticTag": "qualifier value","languageCode": "en","caseSignificance": {
"id": "900000000000448009"
},"concept": {
"id": "258674000"
},"type": {
"id": "900000000000003001"
},"caseSignificanceId": "900000000000448009","acceptability": {}
},{
"id": "384891018","iconId": "900000000000013009","semanticTag": "","caseSignificance": {
"id": "900000000000017005"
},"type": {
"id": "900000000000013009"
},"caseSignificanceId": "900000000000017005","acceptability": {
"900000000000509007": "PREFERRED","900000000000508004": "PREFERRED"
}
},{
"id": "650119013","effectiveTime": "20060731","term": "um (qualifier value)",{
"id": "384888018","term": "micrometer",{
"id": "3508354011",{
"id": "3508411019","term": "Micrometer","acceptability": {
"900000000000509007": "ACCEPTABLE"
}
},{
"id": "384889014","term": "micrometre","acceptability": {
"900000000000508004": "ACCEPTABLE"
}
},{
"id": "384890017","term": "micron","acceptability": {
"900000000000509007": "ACCEPTABLE","900000000000508004": "ACCEPTABLE"
}
}
],"limit": 8,"total": 8
},"ancestorIds": [
"-1","138875005","258667005","362981000","767524001"
],"parentIds": [
"258668000"
],"statedAncestorIds": [
"-1","statedParentIds": [
"258668000"
],"definitionStatusId": "900000000000074008"
}
],"searchAfter": "AoE_BTAxMzRlZWNhLTYxODEtNDFjYi1hNmJlLWQzN2IwMGFlYzEyNA==","limit": 50,"total": 1
}
JSON中的顶级对象表示M语言术语的记录列表。使用查询服务器的自定义函数fromServer(endpoint)
,我可以使用-
let
concepts = Table.FromRecords(fromServer("API_ENDPOINT")[items]),in
concepts
这给了我一张概念表,每行一个。但是我被困在下一点。
每个概念都有一组可能的同义词。这些是SNOMED术语的描述。上述表格中的descriptions
列是“记录”列,其中每个记录都有一个字段items
。 items
是记录的列表,并且记录包含要访问的键/值对。我想做的是展开descriptions
列,按名称展开选定的值,或展开最底层“记录”中的所有值。
因此,这类似于Table.ExpandTableColumn()
,其中要扩展的值来自形状列-
descriptions (the column name)
Records
items: List
Records
Keys : Values
我必须承认,我不确定该如何着手,逐步进入表字段中的嵌套结构化值,然后累积结果。任何指针将不胜感激。
解决方法
如果我正确理解了您的问题,则认为您正在采取以下措施:
let
json = "{""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"",""type"":{""id"":""900000000000013009""},""typeId"":""900000000000013009"",""descriptions"":{""items"":[{""id"":""2609609012"",""active"":false,""effectiveTime"":""20170731"",""iconId"":""900000000000003001"",""term"":""micrometer (qualifier value)"",""semanticTag"":""qualifier value"",""languageCode"":""en"",""caseSignificance"":{""id"":""900000000000448009""},""caseSignificanceId"":""900000000000448009"",""acceptability"":{}},{""id"":""384891018"",""iconId"":""900000000000013009"",""semanticTag"":"""",""caseSignificance"":{""id"":""900000000000017005""},""caseSignificanceId"":""900000000000017005"",{""id"":""650119013"",""effectiveTime"":""20060731"",""term"":""um (qualifier value)"",{""id"":""384888018"",""term"":""micrometer"",{""id"":""3508354011"",{""id"":""3508411019"",""term"":""Micrometer"",""acceptability"":{""900000000000509007"":""ACCEPTABLE""}},{""id"":""384889014"",""term"":""micrometre"",""acceptability"":{""900000000000508004"":""ACCEPTABLE""}},{""id"":""384890017"",""term"":""micron"",""acceptability"":{""900000000000509007"":""ACCEPTABLE"",""900000000000508004"":""ACCEPTABLE""}}],""limit"":8,""total"":8},""ancestorIds"":[""-1"",""138875005"",""258667005"",""362981000"",""767524001""],""parentIds"":[""258668000""],""statedAncestorIds"":[""-1"",""statedParentIds"":[""258668000""],""definitionStatusId"":""900000000000074008""}],""searchAfter"":""AoE_BTAxMzRlZWNhLTYxODEtNDFjYi1hNmJlLWQzN2IwMGFlYzEyNA=="",""limit"":50,""total"":1}",parsed = Json.Document(json),toTable = Table.FromRecords(parsed[items]),flattenedDescriptions = Table.TransformColumns(toTable,{"descriptions",each Table.FromRecords([items]),type table}),// If the columns you want to expand are fixed/constant,you can hard code them. Something like this.
expandHardCoded = Table.ExpandTableColumn(flattenedDescriptions,"descriptions",{"id","released","active","effectiveTime","moduleId","iconId","term","semanticTag","languageCode","caseSignificance","concept","type","typeId","conceptId","caseSignificanceId","acceptability"},{"id.1","released.1","active.1","effectiveTime.1","moduleId.1","iconId.1","acceptability"}),// If the columns you want to expand need to be determined dynamically but every table will have the same column names,then can look at first table and use its column names when expanding.
expandBasedOnFirstRowOnly =
let
columnsToExpand = Table.ColumnNames(flattenedDescriptions{0}[descriptions]),renamed = List.Transform(columnsToExpand,each "descriptions." & _),expanded = Table.ExpandTableColumn(flattenedDescriptions,columnsToExpand,renamed)
in expanded,// If the columns you want to expand need to be determined dynamically but every table will not have the same column names,then create an exhaustive,unique list. This goes through every row in the table though,so might be a little slower.
expandBasedOnAllRows =
let
columnsToExpand = List.Distinct(List.Combine(List.Transform(flattenedDescriptions[descriptions],Table.ColumnNames))),renamed)
in expanded
in
expandBasedOnAllRows
-
Table.TransformColumns
将遍历descriptions
列中的每个值,并将每个值的items
字段转换为表格-然后可以对其进行扩展。 -
expandHardCoded
,expandBasedOnFirstRowOnly
,expandBasedOnAllRows
步骤只是扩展嵌套列的三种不同方法。根据您要处理的数据的性质,(n)您可能不适合使用这些方法中的一种。