Synapse SQL を使って Cosmos DB のクエリを実行する

完了

Spark プールを使うだけでなく、Azure Synapse Analytics に組み込まれた "サーバーレス" SQL プールを使って Azure Cosmos DB 分析コンテナーのクエリを実行することもできます。 これを行うには、OPENROWSET SQL 関数を使って、Azure Cosmos DB データベースのリンク サービスに接続します。

認証キーを使った OPENROWSET の使用

既定では、Azure Cosmos DB アカウントへのアクセスは認証キーで認証されます。 次の例に示すように、このキーを OPENROWSET ステートメントの接続文字列の一部として使うと、SQL プールからリンク サービスを介して接続できます。

SELECT *
FROM OPENROWSET(​
    'CosmosDB',
    'Account=my-cosmos-db;Database=my-db;Key=abcd1234....==',
    [my-container]) AS products_data

ヒント

Cosmos DB アカウントのプライマリとセカンダリのキーは、Azure portal の [キー] ページで確認できます。

このクエリの結果は、Azure Cosmos DB コンテナー内の項目のメタデータとアプリケーション定義フィールドを含めて、次のようになります。

_rid _ts productID productName id _etag
mjMaAL...== 1655414791 123 ウィジェット 7248f072-11c3-42b1-a368-... 54004b09-0000-2300-...
mjMaAL...== 1655414829 124 Wotsit dc33131c-65c7-421a-a0f7-... 5400ca09-0000-2300-...
mjMaAL...== 1655414835 125 Thingumy ce22351d-78c7-428a-a1h5-... 5400ca09-0000-2300-...
... ... ... ... ... ...

データは分析ストアから取得され、クエリは運用ストアに影響を与えません。

資格情報での OPENROWSET の使用

OPENROWSET の各呼び出しに認証キーを含めるのではなく、Cosmos DB アカウントの認証情報をカプセル化した "資格情報" を定義し、以降のクエリでその資格情報を使用できます。 資格情報を作成するには、次の例に示すように CREATE CREDENTIAL ステートメントを使います。

 CREATE CREDENTIAL my_credential
 WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
 SECRET = 'abcd1234....==';

資格情報を設定すると、次のように OPENROWSET 関数で使用できます。

SELECT *
FROM OPENROWSET(​PROVIDER = 'CosmosDB',
                CONNECTION = 'Account=my-cosmos-db;Database=my-db',
                OBJECT = 'my-container',
                SERVER_CREDENTIAL = 'my_credential'
) AS products_data

この場合も、分析ストアのメタデータとアプリケーション定義のフィールドが結果に含まれます。

_rid _ts productID productName id _etag
mjMaAL...== 1655414791 123 ウィジェット 7248f072-11c3-42b1-a368-... 54004b09-0000-2300-...
mjMaAL...== 1655414829 124 Wotsit dc33131c-65c7-421a-a0f7-... 5400ca09-0000-2300-...
mjMaAL...== 1655414835 125 Thingumy ce22351d-78c7-428a-a1h5-... 5400ca09-0000-2300-...
... ... ... ... ... ...

スキーマの指定

OPENROWSET 構文には WITH 句があり、これを使って結果の行セットのスキーマを定義することができます。 次の例に示すように、これを使って個々のフィールドを指定し、データ型を割り当てることができます。

 SELECT *
 FROM OPENROWSET(​PROVIDER = 'CosmosDB',
                 CONNECTION = 'Account=my-cosmos-db;Database=my-db',
                 OBJECT = 'my-container',
                 SERVER_CREDENTIAL = 'my_credential'
 )
 WITH (
    productID INT,
    productName VARCHAR(20)
 ) AS products_data

この場合、分析ストアのフィールドに productIDproductName が含まれているとすると、結果の行セットは次のような表になります。

productID productName
123 ウィジェット
124 Wotsit
125 Thingumy
... ...

もちろん、SELECT 句で個別の列名を指定できるので (例: SELECT productID, productName ...)、このように個別の列を指定する機能は使い道が限られているように見えるかもしれません。 一方で、次の例のように、運用ストアに格納されるソース JSON ドキュメントに、複数レベルのフィールドが含まれる場合を考えてみてください。

{
    "productID": 126,
    "productName": "Sprocket",
    "supplier": {
        "supplierName": "Contoso",
        "supplierPhone": "555-123-4567"
    }
    "id": "62588f072-11c3-42b1-a738-...",
    "_rid": "mjMaAL...==",
    ...
}

WITH 句は明示的な JSON パスを含めることをサポートしており、次の例に示すように、入れ子になったフィールドを処理し、フィールド名に別名を割り当てることができます。

 SELECT *
 FROM OPENROWSET(​PROVIDER = 'CosmosDB',
                 CONNECTION = 'Account=my-cosmos-db;Database=my-db',
                 OBJECT = 'my-container',
                 SERVER_CREDENTIAL = 'my_credential'
 )
 WITH (
    ProductNo INT '$.productID',
    ProductName VARCHAR(20) '$.productName',
    Supplier VARCHAR(20) '$.supplier.supplierName',
    SupplierPhoneNo VARCHAR(15) '$.supplier.supplierPhone'
 ) AS products_data

このクエリの結果、製品 126 に対して次の行が含まれます。

ProductNo ProductName Supplier (仕入先) SupplierPhoneNo
126 Sprocket Contoso 555-123-4567

データベースでのビューの作成

同じデータに対して頻繁にクエリを実行する必要がある場合、または OPENROWSET 関数を含まない SELECT ステートメントを利用するレポート作成や視覚化のツールを使う必要がある場合は、"ビュー" を使ってデータを抽象化することができます。 ビューを作成するには、次の例に示すように、それを定義する新しいデータベースを作成する必要があります ("マスター" データベース内のユーザー定義ビューはサポートされていません)。

CREATE DATABASE sales_db
   COLLATE Latin1_General_100_BIN2_UTF8;
 GO;

 USE sales_db;
 GO;

 CREATE VIEW products
 AS
 SELECT *
 FROM OPENROWSET(​PROVIDER = 'CosmosDB',
                 CONNECTION = 'Account=my-cosmos-db;Database=my-db',
                 OBJECT = 'my-container',
                 SERVER_CREDENTIAL = 'my_credential'
 )
 WITH (
    ProductNo INT '$.productID',
    ProductName VARCHAR(20) '$.productName',
    Supplier VARCHAR(20) '$.supplier.supplierName',
    SupplierPhoneNo VARCHAR(15) '$.supplier.supplierPhone'
 ) AS products_data
 GO

ヒント

Cosmos DB のデータにアクセスするデータベースを作成する場合、Cosmos DB 内の文字列との互換性を確保するために、UTF-8 ベースの照合順序を使うことをお勧めします。

ビューを作成したら、ユーザーとクライアント アプリケーションは、他の SQL ビューまたはテーブルと同様にクエリを実行できます。

SELECT * FROM products;

サーバーレス SQL プールと Azure Cosmos DB に関する考慮事項

サーバーレス SQL プールを使って Azure Cosmos DB 分析ストアのデータに対してクエリを実行する予定がある場合、次のベスト プラクティスを検討してください。

  • Azure Cosmos DB 分析ストレージとクライアント アプリケーション (たとえば Microsoft Power BI) をサーバーレス SQL プールと同じリージョンにプロビジョニングします。

    Azure Cosmos DB コンテナーは、複数のリージョンにレプリケートできます。 複数リージョンのコンテナーがある場合、OPENROWSET 接続文字列に region パラメーターを指定することで、コンテナーの特定のリージョン レプリカにクエリを確実に送信できます。

  • 文字列の列を操作する場合は、明示的な WITH 句と共に OPENROWSET 関数を使い、文字列データに適切なデータ長を指定します。