如何在 CDC 管道中的全保真分析存储架构中使用字符串属性?

问题描述 投票:0回答:1

我有一个使用 MongoDB API 的 CosmosDB 帐户,并且正在尝试使用其更改数据捕获输出。

我具体看到的问题是完全保真度

string
属性的工作方式似乎与其他完全保真度属性不同,并且不清楚如何使用它们并在转换中成功访问这些值。

TLDR 是

据我所知,全保真字符串类型的属性似乎最终有 two 子属性,都名为

stringas
- 一个为空/空,一个具有实际值。这个分析正确吗?我如何获取实际值?

完整再现

在新创建的 MongoDB 集合中,我插入一个文档

{
    "_id" : "1",
    "firstName" : "Thomas",
    "lastName" : "Andersen",
    "addresses" : [
        {
            "line1" : "100 Some Street",
            "line2" : "Unit 1",
            "city" : "Seattle",
            "state" : "WA",
            "zip" : 98012
        }
    ],
    "contactDetails" : [
        {
            "email" : "[email protected]"
        },
        {
            "phone" : "+1 555 555-5555",
            "extension" : 5555
        }
    ]
}

然后使用提供查询的选项设置连接到该集合中的分析存储的 CDC 管道,如下所示

SELECT _id.string AS _id,
       firstName.string AS firstName,
       lastName.string AS lastName,
       addresses.array AS addresses,
       contactDetails.array AS contactDetails
FROM c 

导入投影后,它返回以下内容(扩展了路径样本)。这几乎符合全保真模式的预期,除了由于某种原因字符串属性被称为

stringas

enter image description here

我只想向下游发送属性的子集,并且还想简化架构并删除完整的保真度伪影,因此我添加了一个派生列转换,其中包含名为

addresses
的单个列和以下定义

map(addresses,     
        @(line1 = #item.object.line1.stringas,
            zip = #item.object.zip.int32    ))

其目的是将地址元素中的每个数组元素替换为一个更简单的元素,该元素仅包含两个包含原始值的属性(

line1
zip
)。

最后我将整个内容推入 JSON 接收器

结果

{
  "_rid": "2Uo7APnUuK8BAAAAAAAAAA==",
  "_ts": 1731422138,
  "_id": "1",
  "firstName": "Thomas",
  "lastName": "Andersen",
  "addresses": [ { "zip": 98012 } ],
  "contactDetails": [
    {
      "object": {
        "email": { "string": "[email protected]" },
        "phone": {}
      }
    },
    {
      "object": {
        "email": {},
        "phone": { "string": "+1 555 555-5555" },
        "extension": { "int32": 5555 }
      }
    }
  ],
  "__usr_opType": 2
}

问题

对于

addresses
元素,
zip
的映射按预期工作,但映射
line1
的尝试在输出中没有留下任何痕迹!

顺便说一句,我也注意到 contactDetails 元素的属性名称确实在输出中自动更改为

string
,尽管在架构中显示为
stringas

当我查看源中的“数据预览”时,我想我可以明白为什么

line1
可能会丢失......

line1
属性似乎有two子“
stringas
”属性 - 一个为空/空,另一个具有实际值。看起来我的派生列转换正在使用这些属性中的第一个,我如何访问具有实际值的属性?

enter image description here

azure-data-factory azure-cosmosdb azure-cosmosdb-mongoapi azure-synapse-pipeline
1个回答
0
投票

我找到了一个解决方案。

我不确定幕后发生了什么“魔法”,也不知道我们如何看到这一点,但我发现

toString(#item.object.line1)
返回了
{"string":"100 Some Street"}

因此,对于我的用例,我可以执行一些子字符串操作来删除前 11 个字符和最后 2 个字符以获得实际值。

map(addresses,     
        @(line1 = substring(toString(#item.object.line1), 12, length(toString(#item.object.line1)) - 13) ,
            zip = #item.object.zip.int32    ))
© www.soinside.com 2019 - 2024. All rights reserved.