随着时间的推移,使用不同大小写的键跨相同的 JSON_B 嵌套进行查询

Querying across identical JSON_B nests with Keys in different case over time

我必须在 json_b 字段中存储多个包含嵌套(3-5 级)JSON 特定于我们的呼叫中心应用程序的字段。然后,我们根据我们的分析需求具体化视图,并将执行报告视图推送到 Redshift。数据最初是从 S3 源提取的,该源是 lambda 函数的备份,该函数解析日志流并将其作为 parquet

放入 S3

将JSON以Parquettable加载的数据格式如下:

{"ContactId": "val", "Timestamp": "2021-06-02T03:59:59.094Z", "Parameters": {"Text": "Para português, aperte três.", "Voice": "name", "Timeout": "3000", "MaxDigits": "1", "TextToSpeechType": "text"}, "ContactFlowId": "arn:-1993633fcebb", "ContactFlowModuleType": "GetUserInput"}

随着上游移除 lambda 并放入 Kinesis Firehose 以将数据登陆到 parquet 中的相同位置,这现已发生变化。这些字段的新负载如下所示:

{"contactid": "val", "timestamp": "2021-06-02T03:59:59.094Z", "parameters": {"text": "Para português, aperte três.", "voice": "name", "timeout": "3000", "maxdigits": "1", "texttospeechtype": "text"}, "contactflowid": "arn:-1993633fcebb", "contactflowmoduletype": "GetUserInput"}

直到非产品中的 ETL 开始表现不正确,然后物化视图开始加载错误,但事实证明以前使用原始 key/value 对定义的查询,我们才立即意识到影响即使在字段名称或嵌套结构方面没有任何变化,也没有被解析。

所以:

message->>'ContactId' is distinct from message->>'contactid'. 

问题是我们现在在我们的核心 table 中拥有两组嵌套。我查看了 Firehose,它没有提供保留按键外壳的选项。

我可以使用 CASE 语句基于时间定义 mat 视图,因为有不同的切换日期,但我想知道我如何处理切换到 firehose 之前和之后跨越时间的查询。

最初的想法是使用 COALESCE(message->>'ContactId', message->>'contactid') 但当尝试重构涉及跨不同嵌套级别的聚合的查询时,这很快变得难看。

关于我如何最好地解决这个问题的任何想法。除了 mat 视图之外,我们还在从阶段到目标的触发器函数中查询此嵌套,再到将值转换为特定数据类型的位置,因此对于我们的某些批处理加载而言,相关的合并可能在计算上过于密集。

任何 thoughts/ideas 将不胜感激。

谢谢

考虑到除了上游修正之外没有更好的选择,选择了 COALESCE。