如何计算 JSON 中所有值的路径

How to work out the path for all values in a JSON

我有一个 JSON 列,其中包含大约 300k 的属性,我想尝试以这样一种方式导出它,以便我可以获得 属性 的完整路径和值. 请注意,我的 JSON 没有数组 - 它基本上是用于 Web 应用程序翻译的 JSON。

使用以下内容提供一个简单示例 JSON 我想返回以下内容:

JSON: {"Name":"Jeff", "Address": {"Street": "123 Harrow Street", "City": "Dublin"}}

预期输出:

|----------------|-------------------|
| path           |  value            |
|----------------|-------------------|
| Name           | Jeff              |
| Address.Street | 123 Harrow Street |
| Address.City   | Dublin            |
|----------------|-------------------|

或者如果使用 $. 更容易,因为我希望能够轻松更新每个 属性 的值 - 使用 JSON_MODIFY.

我试过使用 OPENJSON 但那只出现在 return 3 个字段键、值和类型中,但至少这里的键不会超过值的字段级别,所以我得到: 查询:

DECLARE @json_doc nvarchar(4000) = '{"Name":"Jeff", "Address": {"Street": "123 Harrow Street", "City": "Dublin"}}';

SELECT [key], [value]
FROM OPENJSON(@json_doc);
GO

输出:

|---------|---------------------------------------------------|
| key     |  value                                            |
|---------|---------------------------------------------------|
| Name    | Jeff                                              |
| Address | {"Street": "123 Harrow Street", "City": "Dublin"} |
|---------|---------------------------------------------------|

有没有办法让 OPENJSON 查询完全递归?或者还有其他方法吗?我试过谷歌搜索,但它似乎不是一个常见的请求?

递归 CTE 是一种选择。您需要在查询的递归成员中使用 ISJSON() 作为终止条件:

DECLARE @json_doc nvarchar(4000) = '{"Name":"Jeff", "Address": {"Street": "123 Harrow Street", "City": "Dublin"}}';

;WITH rCTE AS (
   SELECT 
       CONVERT(nvarchar(max), N'$') COLLATE DATABASE_DEFAULT AS [path], 
       CONVERT(nvarchar(max), JSON_QUERY(@json_doc, '$')) COLLATE DATABASE_DEFAULT AS [value]
   UNION ALL
   SELECT 
      CONVERT(nvarchar(max), CONCAT(r.path, CONCAT(N'.', c.[key]))) COLLATE DATABASE_DEFAULT ,
      CONVERT(nvarchar(max), c.[value]) COLLATE DATABASE_DEFAULT                                        
   FROM rCTE r
   CROSS APPLY OPENJSON(r.[value]) c
   WHERE ISJSON(r.[value]) = 1
)
SELECT *
FROM rCTE
WHERE ISJSON([value]) = 0

结果:

path             value
----------------------------------
$.Name           Jeff
$.Address.Street 123 Harrow Street
$.Address.City   Dublin