Azure Synapse Analytics'te karmaşık veri türlerini analiz etme

Önemli

Cosmos DB için Synapse Link artık yeni projeler için desteklenmemektedir. Bu özelliği kullanmayın.

Microsoft Fabric için artık Genel Kullanılabilirlikte olan Azure Cosmos DB Yansıtmayı kullanın. Yansıtma aynı sıfır ETL avantajlarını sağlar ve Microsoft Fabric ile tamamen tümleşiktir. Cosmos DB Yansıtmaya Genel Bakış sayfasında daha fazla bilgi edinin.

Bu makale, Azure Cosmos DB için Azure Synapse Link'teki Parquet dosyaları ve kapsayıcıları için geçerlidir. Diziler veya iç içe yapılar gibi karmaşık şemalarla verileri okumak veya dönüştürmek için Spark veya SQL kullanabilirsiniz. Aşağıdaki örnek tek bir belgeyle tamamlanmıştır, ancak Spark veya SQL ile milyarlarca belgeye kolayca ölçeklendirilebilir. Bu makalede yer alan kod PySpark (Python) kullanır.

Kullanım örneği

Karmaşık veri türleri giderek yaygın hale geldi ve veri mühendisleri için bir zorluğu temsil ediyor. İç içe şemayı ve dizileri çözümlemek zaman alan ve karmaşık SQL sorguları içerebilir. Buna ek olarak, iç içe sütunların veri türünü yeniden adlandırmak veya atamak zor olabilir. Ayrıca, iç içe nesnelerle çalışırken performans sorunlarıyla karşılaşabilirsiniz.

Veri mühendislerinin karmaşık veri türlerini verimli bir şekilde işlemeyi ve bunların herkes tarafından kolayca erişilebilir olmasını sağlamayı anlaması gerekir. Aşağıdaki örnekte, veri çerçeveleri aracılığıyla nesneleri okumak ve düz bir yapıya dönüştürmek için Azure Synapse Analytics'te Spark'ı kullanırsınız. Bu tür nesneleri doğrudan sorgulamak ve bu sonuçları normal bir tablo olarak döndürmek için Azure Synapse Analytics'te sunucusuz SQL modelini kullanırsınız.

Diziler ve iç içe yapılar nedir?

Aşağıdaki nesne Application Insights'tan gelir. Bu nesnede iç içe yapılar ve iç içe yapılar içeren diziler vardır.

{
    "id": "66532691-ab20-11ea-8b1d-936b3ec64e54",
    "context": {
        "data": {
            "eventTime": "2020-06-10T13:43:34.553Z",
            "samplingRate": "100.0",
            "isSynthetic": "false"
        },
        "session": {
            "isFirst": "false",
            "id": "38619c14-7a23-4687-8268-95862c5326b1"
        },
        "custom": {
            "dimensions": [
                {
                    "customerInfo": {
                        "ProfileType": "ExpertUser",
                        "RoomName": "",
                        "CustomerName": "diamond",
                        "UserName": "XXXX@yahoo.com"
                    }
                },
                {
                    "customerInfo": {
                        "ProfileType": "Novice",
                        "RoomName": "",
                        "CustomerName": "topaz",
                        "UserName": "XXXX@outlook.com"
                    }
                }
            ]
        }
    }
}

Dizilerin ve iç içe yapıların şema örneği

komutuyla nesnenin veri çerçevesinin (dfdf.printschema) şemasını yazdırırken aşağıdaki gösterimi görürsünüz:

  • Sarı iç içe yapıları temsil eder.
  • Yeşil, iki öğe içeren bir diziyi temsil eder.

Şema kaynağını gösteren sarı ve yeşil vurgulamalı kod

_rid, _tsve _etag belge Azure Cosmos DB işlem deposuna alınırken sisteme eklendi.

Önceki veri çerçevesi yalnızca 5 sütun ve 1 satır için sayılır. Dönüştürmeden sonra, seçilen veri çerçevesinin tablo biçiminde 13 sütunu ve 2 satırı olur.

İç içe yapıları düzleştirme ve dizileri patlatma

Azure Synapse Analytics'teki Spark ile iç içe yapıları sütunlara ve dizi öğelerini birden çok satıra dönüştürmek kolaydır. Uygulama için aşağıdaki adımları kullanın.

Spark dönüştürme adımlarını gösteren akış çizelgesi

İç içe şemayı düzleştirmeye ilişkin bir işlev tanımlama

Bu işlevi değişiklik yapmadan kullanabilirsiniz. PySpark not defterinde aşağıdaki işleve sahip bir hücre oluşturun:

from pyspark.sql.functions import col

def flatten_df(nested_df):
    stack = [((), nested_df)]
    columns = []

    while len(stack) > 0:
        parents, df = stack.pop()

        flat_cols = [
            col(".".join(parents + (c[0],))).alias("_".join(parents + (c[0],)))
            for c in df.dtypes
            if c[1][:6] != "struct"
        ]

        nested_cols = [
            c[0]
            for c in df.dtypes
            if c[1][:6] == "struct"
        ]

        columns.extend(flat_cols)

        for nested_col in nested_cols:
            projected_df = df.select(nested_col + ".*")
            stack.append((parents + (nested_col,), projected_df))

    return nested_df.select(columns)

İşlevi kullanarak iç içe şemayı düzleştirme

Bu adımda, veri çerçevesinin (df) iç içe geçmiş şemasını düzleştirerek yeni bir veri çerçevesine (df_flat) dönüştürürsünüz.

from pyspark.sql.types import StringType, StructField, StructType
df_flat = flatten_df(df)
display(df_flat.limit(10))

Görüntüleme işlevi 10 sütun ve 1 satır döndürmelidir. Dizi ve iç içe geçmiş öğeleri hala mevcuttur.

Diziyi dönüştürme

Burada, veri çerçevesindeki context_custom_dimensionsdizisini df_flatyeni bir veri çerçevesine df_flat_explodedönüştürebilirsiniz. Aşağıdaki kodda, hangi sütunun seçılacağını da tanımlarsınız:

from pyspark.sql.functions import explode
from pyspark.sql.functions import flatten
from pyspark.sql.functions import arrays_zip
df_flat_explode = df_flat.select("_rid","_ts","id","_etag",explode(df_flat.context_custom_dimensions),"context_session_isFirst","context_session_id","context_data_eventTime","context_data_samplingRate","context_data_isSynthetic")\
.select("_rid","_ts","id","_etag","col.*","context_session_isFirst","context_session_id","context_data_eventTime","context_data_samplingRate","context_data_isSynthetic")
display(df_flat_explode.limit(10))

Görüntüleme işlevi 10 sütun ve 2 satır döndürmelidir. Sonraki adım, 1. adımda tanımlanan işlevle iç içe şemaları düzleştirmedir.

İşlevi kullanarak iç içe şemayı düzleştirme

Son olarak, işlevini kullanarak veri çerçevesinin df_flat_explodeiç içe şemasını yeni bir veri çerçevesine df_flat_explode_flatdüzleştirirsiniz:

df_flat_explode_flat = flatten_df(df_flat_explode)
display(df_flat_explode_flat.limit(10))

Display işlevi 13 sütun ve 2 satır göstermelidir.

Veri çerçevesinin printSchema işlevi df_flat_explode_flat aşağıdaki sonucu döndürür:

Son şemayı gösteren kod

Dizileri ve iç içe yapıları doğrudan okuma

SQL'in sunucusuz modeliyle, bu tür nesneler üzerinde görünümler ve tablolar sorgulayabilir ve oluşturabilirsiniz.

İlk olarak, verilerin nasıl depolandığına bağlı olarak, kullanıcılar aşağıdaki taksonomiyi kullanmalıdır. Büyük harfle gösterilen her şey kullanım örneğine özeldir:

Toplu Biçim
https://ACCOUNTNAME.dfs.core.windows.net/FILESYSTEM/PATH/FINENAME.parquet 'Parquet' (ADLSg2)
N'endpoint=https://ACCOUNTNAME.documents.azure.com:443/;account=ACCOUNTNAME;database=DATABASENAME;collection=COLLECTIONNAME;region=REGIONTOQUERY', SECRET='YOURSECRET' CosmosDB (Azure Synapse Link)

Her alanı aşağıdaki gibi değiştirin:

  • 'YOUR BULK ABOVE', bağlandığınız veri kaynağının bağlantı dizesidir.
  • 'Yukarıdaki tür' kaynağa bağlanmak için kullandığınız biçimdir.
select *
FROM
openrowset(
    BULK 'YOUR BULK ABOVE',
    FORMAT='YOUR TYPE ABOVE'
)
with (id varchar(50),
        contextdataeventTime varchar(50) '$.context.data.eventTime',
        contextdatasamplingRate varchar(50) '$.context.data.samplingRate',
        contextdataisSynthetic varchar(50) '$.context.data.isSynthetic',
        contextsessionisFirst varchar(50) '$.context.session.isFirst',
        contextsessionid varchar(50) '$.context.session.id',
        contextcustomdimensions varchar(max) '$.context.custom.dimensions'
) as q 
cross apply openjson (contextcustomdimensions) 
with ( ProfileType varchar(50) '$.customerInfo.ProfileType',
            RoomName varchar(50) '$.customerInfo.RoomName',
            CustomerName varchar(50) '$.customerInfo.CustomerName',
            UserName varchar(50) '$.customerInfo.UserName'
    )

İki farklı işlem türü vardır:

  • İlk işlem türü, iç içe öğe contextdataeventTime ile ilgili olan ve Context.Data.eventTime adlı sütunu tanımlayan aşağıdaki kod satırında gösterilir.

    contextdataeventTime varchar(50) '$.context.data.eventTime'
    

    Bu satır, contextdataeventTime iç içe geçmiş öğeye başvuran Context>Data>eventTime adlı sütunu tanımlar.

  • İkinci işlem türü, dizi altındaki her öğe için yeni satırlar oluşturmak için kullanır cross apply . Ardından iç içe her nesneyi tanımlar.

    cross apply openjson (contextcustomdimensions) 
    with ( ProfileType varchar(50) '$.customerInfo.ProfileType', 
    

    Dizide 4 iç içe yapıya sahip 5 öğe varsa, SQL'in sunucusuz modeli 5 satır ve 4 sütun döndürür. SQL'in sunucusuz modeli yerinde sorgulayabilir, diziyi 2 satır halinde eşleyebilir ve iç içe tüm yapıları sütunlar halinde görüntüleyebilir.

Sonraki adımlar