MoreBeerMorePower

Power Platform中心だけど、ノーコード/ローコード系を書いてます。

【備忘録】Cosmos DBのリソース作成~複合インデックスの定義まで

Power Automate での データ置き場はSharePointリストとかDataverseとかExcelとかいろいろ選べるんですが、Logic Appsの時はどうしようかなーと思ってどうせならAzureのサービスをということでCosmos DBを使ったときの備忘録です。

今回やりたいのは、前回の投稿で紹介したようなPower Automate/Logic Appsでの配列のソート(特に第二ソート条件まで使うようなケース)です。

Cosmos DBなら、複合インデックスというものを定義すれば2つの列でソートするということも可能なようです。

リソース作成

リソース作成くらい躓かないだろうと思ってました...

f:id:mofumofu_dance:20220204105250p:plain

「Wichi API ...」って何?!

どうやらCosmos DBではデータモデルに応じて最適なAPIが用意されているようです。今回はあまり考えずに推奨されている「Core (SQL)」を選びました。

あとは他のリソース同様に、サブスクリプションやリソースグループを指定していきます。画像では非活性になっていますが、「Apply Free Tier Discount」にチェックを入れて作成しています。

f:id:mofumofu_dance:20220204105751p:plain

リソースの作成はこれで終わり。

データベース作成

データベースを作っていきます。

実際データを登録するには、データベース作成→コンテナ作成 というステップを踏みました。

f:id:mofumofu_dance:20220204110913p:plain

データベーススループットはManualにしています。データベースが作成されたら、続いてコンテナをその中に作成します。

ここで、IndexingAutomatic に、Partition Key はあとで使う /guidをそれぞれ設定しています。

パーティションキーについてはReferenceの中で以下のように記載されていました。

同一パーティションキー値のデータにおいてのみトランザクション処理が可能 パーティションキーはデータがなるべく均等に分散されるように設定する データの偏りが発生した場合、対象のパーティションにのみ負荷がかかり、予約設定したスループット(RU)のパフォーマンスがでなくなる。

Azure Cosmos DB入門(2) - ryuichi111stdの技術日記

なるほど。よくわからんけど、今回はRead APIの結果を登録する際に、GUIDを発行してどのスキャンの結果なのかを区別しているので、そのguidをパーティションキーとしておくんでよさそうです。

これでアイテム登録ができるようになりました。

アイテム登録、複合インデックス定義

実際に想定されるデータを登録してみます。

データの登録には「New Item」から。必要な構成のJSONオブジェクトを書きます。

今回の場合は以下のようなJSONを書いてデータを登録しました。

{
    "guid": "024DEE41-33E7-11D3-9D69-0008C781F39F",
    "text": "AAAAA",
    "txtTop": 32,
    "txtLeft": 21,
    "txtRight": 35.2
}

f:id:mofumofu_dance:20220204113544p:plain

あとは最初に書いた複合インデックスの設定です。

作成したコンテナを開くと「Settings」という項目があります。この中の「Indexing Policy」というところで、複合インデックスを指定します。今回のケースでは"top"と"left"という数値型の列でソートしたいので、以下のように設定しています。

    "compositeIndexes":[
        [
            {
                "path":"/txtTop",
                "order":"ascending"
            },
            {
                "path":"/txtLeft",
                "order":"ascending"
            }
        ],
        [
            {
                "path":"/txtLeft",
                "order":"ascending"
            },
            {
                "path":"/txtTop",
                "order":"ascending"
            }
        ]
    ]

テスト

複数のデータを登録して、ソート (ORDER BY)の結果が期待通りかを見てみましょう。

[
  {
    "text": "AAAAA",
    "txtTop": 38,
    "txtLeft": 25,
    "txtRight": 35.2
  },
  {
    "text": "BBBBB",
    "txtTop": 36,
    "txtLeft": 23,
    "txtRight": 35.2
  },
  {
    "text": "CCCCC",
    "txtTop": 32,
    "txtLeft": 25,
    "txtRight": 35.2
  },
  {
    "text": "DDDDD",
    "txtTop": 32,
    "txtLeft": 21,
    "txtRight": 35.2
  }
]

こんなデータを登録して、top asc, left ascでソートします。期待されるのは"DDDDD"->"CCCCC" -> "BBBBB" -> "AAAAA"となることです。

実際にクエリを実行すると以下のように期待通りの結果が得られました。

f:id:mofumofu_dance:20220204130745p:plain

ハマったところ

最初、キーの名前を"top"や"left"にしていたんですが、これだと何故かORDER BYでエラーが出てしまいました。(code":"SC1001"でシンタックスエラー) なんでか未だに不明ですが、キーの名前を上記の通り変更したところ正常にORDER BYもSELECTもできるようになっています。たぶん何らかの予約語とぶつかっていたのかもしれません。

参考

下記のブログに大変お世話になりました。最新のポータル上での表示だと、「コレクション」が「コンテナー」に変わっていますが、読み替えれば手順は同じです。

ryuichi111std.hatenablog.com

ryuichi111std.hatenablog.com