【问题标题】:PowerQuery M Language- expand a column of type "List of Records of Lists of Records"PowerQuery M Language - 展开类型为“List of Records of Records”的列
【发布时间】:2020-09-09 16:49:02
【问题描述】:

我正在使用 Excel Powerquery(M 语言)访问 SNOMED CT 服务器的 RESTful API。服务器返回的 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",
        "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
}

JSON 中的顶级对象表示 M 语言术语中的记录列表。使用自定义函数 fromServer(endpoint) 查询服务器,我能够使用扩展 JSON 结果-

let
    concepts = Table.FromRecords(fromServer("API_ENDPOINT")[items]),
in
    concepts

这给了我一张概念表,每行一个。但是我被困在下一点。

每个概念都有一组可能的同义词。这些是 SNOMED 术语中的描述。上表中descriptions列是Records列,其中每条Record都有一个字段itemsitems是一个记录列表,记录包含要访问的键/值对。我想要做的是展开descriptions 列,按名称展开选定的值,或者展开底层记录中的所有值。

所以,这类似于Table.ExpandTableColumn(),其中要扩展的值来自形状列-

descriptions (the column name)
  Records
    items: List
      Records
        Keys : Values

我必须承认我不知道如何开始,在表格字段中进入嵌套结构化值,然后累积结果。任何指针将不胜感激。

【问题讨论】:

    标签: json powerquery m


    【解决方案1】:

    如果我正确理解你的问题,我想你是在追求这样的事情:

    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"",""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}",
        
        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", "term", "semanticTag", "languageCode", "caseSignificance", "concept", "type", "typeId", "conceptId", "caseSignificanceId", "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, "descriptions", 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 = List.Transform(columnsToExpand, each "descriptions." & _),
                expanded = Table.ExpandTableColumn(flattenedDescriptions, "descriptions", columnsToExpand, renamed)
            in expanded
    in
        expandBasedOnAllRows
    
    • Table.TransformColumns 将遍历 descriptions 列中的每个值,并将每个值的 items 字段转换为一个表格 - 随后可以展开该表格。
    • expandHardCodedexpandBasedOnFirstRowOnlyexpandBasedOnAllRows 步骤只是扩展嵌套列的三种不同方法。根据您处理的数据的性质,(n)其中一种方法可能适合您。

    【讨论】:

    • 谢谢,这看起来很有帮助。我还需要一段时间才能回到这项工作尝试一下,但当我这样做时,我会回来确认它是否解决了问题。
    猜你喜欢
    • 1970-01-01
    • 2022-12-27
    • 1970-01-01
    • 2022-11-02
    • 2022-12-01
    • 2012-11-29
    • 2021-05-04
    • 1970-01-01
    • 2020-12-04
    相关资源
    最近更新 更多