如何查询嵌套字段并返回路径?

时间:2020-06-22 00:50:21

标签: json sql-server sql-server-2016 sql-server-json

对不起,我的英语不好,而且词汇量少。如何使用"Properties.Searchable" = "true"过滤掉所有字段?这些字段可以是另一个的子字段。

以下是一个示例(已删除大部分不必要的数据):

{
 "Configuration": {
  "Fields": {
   "Id": {
    "Properties": {
      "DataType": "string",
      "Searchable": "true"
    }
   },
   "PrsonalInfo": {
    "BirthDate": {
     "Properties": {
      "DataType": "date",
      "Searchable": "false"
     }
    },
    "Name": {
      "GivenName": {
       "Properties": {
        "DataType": "string",
        "Searchable": "true"
       }
      },
      "FamilyName": {
       "Properties": {
        "DataType": "string",
        "Searchable": "true"
       }
      }
    }
   }
  }
 }
}

我需要查询"Configuration.Fields",仅返回那些具有"Properties.Searchable" = "true"的路径。结果应该类似于或接近于此:

Id
PersonalInfo.Name.GivenName
PersonalInfo.Name.FamilyName

谢谢!

1 个答案:

答案 0 :(得分:1)

我希望这不是一个迟来的答案。一种可能的方法(解析输入的JSON并获得预期的结果)是以下递归CTE:

JSON:

DECLARE @json nvarchar(1000) = N'{
  "Configuration":{
    "Fields":{
      "Id":{
        "Properties":{
          "DataType":"string",
          "Searchable":"true"
        }
      },
      "PrsonalInfo":{
        "BirthDate":{
          "Properties":{
            "DataType":"date",
            "Searchable":"false"
          }
        },
        "Name":{
          "GivenName":{
            "Properties":{
              "DataType":"string",
              "Searchable":"true"
            }
          },
          "FamilyName":{
            "Properties":{
              "DataType":"string",
              "Searchable":"true"
            }
          }
        }
      }
    }
  }
}'

声明:

;WITH rCTE AS (
   SELECT 
       CONVERT(nvarchar(max), N'$') COLLATE DATABASE_DEFAULT AS JsonPath, 
       CONVERT(nvarchar(max), N'$') COLLATE DATABASE_DEFAULT AS JsonKey, 
       CONVERT(nvarchar(max), JSON_QUERY(@json, '$.Configuration.Fields')) COLLATE DATABASE_DEFAULT AS JsonValue
   UNION ALL
   SELECT 
      CONVERT(nvarchar(max), CONCAT(r.JsonPath, CONCAT(N'.', c.[key]))) COLLATE DATABASE_DEFAULT,
      CONVERT(nvarchar(max), c.[key]) COLLATE DATABASE_DEFAULT,
      CONVERT(nvarchar(max), c.[value]) COLLATE DATABASE_DEFAULT                                        
   FROM rCTE r
   CROSS APPLY OPENJSON(r.JsonValue) c
   WHERE ISJSON(r.JsonValue) = 1
)
SELECT JsonPath
FROM rCTE
WHERE 
   CASE 
      WHEN ISJSON(JsonValue) = 1 THEN JSON_VALUE(JsonValue, '$.Properties.Searchable')
      ELSE N'' 
   END = N'true'

结果:

JsonPath
-----------------------------
$.Id
$.PrsonalInfo.Name.GivenName
$.PrsonalInfo.Name.FamilyName