Azure Cosmos DB for NoSQL で JSON を扱う

適用対象: NoSQL

Azure Cosmos DB for NoSQL では、項目は JSON として保存されます。 型システムおよび式は、JSON 型のみを扱うように制限されます。 詳細については、JSON の仕様に関する記事を参照してください。

JSON の扱いで重要な点の一部を次にまとめます。

  • JSON オブジェクトは、常に左中かっこ { で始まり、} 右中かっこで終わる
  • JSON プロパティは、互いに入れ子にすることができる
  • JSON プロパティ値には、配列を使用できる
  • JSON プロパティ名では、大文字と小文字が区別される
  • JSON プロパティ名には、任意の文字列値 (スペースや英文字ではない文字を含む) を使用できる

入れ子になったプロパティ

入れ子の JSON には、ドット (.) アクセサーを使用してアクセスできます。 入れ子になった JSON プロパティは、他のプロパティを使用する場合と同じ方法でクエリで使用できます。

入れ子になった JSON を使用したドキュメントを次に示します。

{
  "name": "Teapo rainbow surfboard",
  "manufacturer": {
    "name": "AdventureWorks"
  },
  "releaseDate": null,
  "metadata": {
    "sku": "72109",
    "colors": [
      "cruise",
      "picton-blue"
    ],
    "sizes": {
      "small": {
        "inches": 76,
        "feet": 6.33333
      },
      "large": {
        "inches": 92,
        "feet": 7.66667
      }
    }
  }
}

この場合、skucolorssizes の各プロパティは、すべて metadata プロパティ内で入れ子になっています。 name プロパティは、manufacturer プロパティ内へも入れ子にされます。

この最初の例では、2 つの入れ子のプロパティをプロジェクトします。

SELECT
    p.name,
    p.metadata.sku,
    p.sizes.small.inches AS size
FROM
    products p
[
  {
    "name": "Teapo rainbow surfboard",
    "sku": "72109"
  }
]

配列の操作

JSON では、入れ子になったプロパティに加えて、配列もサポートされています。 配列を扱う場合、配列内の特定の要素にはその位置を参照することでアクセスできます。

この例では特定の位置にある配列要素にアクセスします。

SELECT
    p.name,
    p.metadata.colors
FROM
    products p
WHERE
    p.metadata.colors[0] NOT LIKE "%orange%"
[
  {
    "name": "Teapo rainbow surfboard",
    "colors": [
      "cruise",
      "picton-blue"
    ]
  }
]

ただし、ほとんどの場合、配列を扱うときはサブクエリまたは自己結合を使用します。

たとえば、候補となる配列値とクロス結合を使用して複数の順列を返すクエリを次に示します。

SELECT
    p.name,
    c AS color
FROM
    products p
JOIN
    c IN p.metadata.colors
[
  {
    "name": "Teapo rainbow surfboard",
    "color": "cruise"
  },
  {
    "name": "Teapo rainbow surfboard",
    "color": "picton-blue"
  }
]

別の例として、クエリはサブクエリで EXISTS を使用することもできます。

SELECT VALUE
    p.name
FROM
    products p
WHERE
    EXISTS (SELECT VALUE 
        c
    FROM
        c IN p.metadata.colors
    WHERE
        c LIKE "%picton%")
[
  "Teapo rainbow surfboard"
]

null 値と未定義の違い

項目内でプロパティが定義されていない場合、その値は undefined になります。 null 値を持つプロパティを明示的に定義し、null 値を割り当てる必要があります。

Azure Cosmos DB for NoSQL では、null および undefined プロパティに対して次の 2 つの便利な型チェック システム関数がサポートされています。

  • IS_NULL - プロパティ値が null かどうかを確認します。
  • IS_DEFINED - プロパティ値が defined と undefined のどちらであるかを確認します。

コンテナー内の各項目で 2 つのフィールドをチェックするクエリの例を次に示します。

SELECT
    IS_NULL(p.releaseDate) AS isReleaseDateNull,
    IS_DEFINED(p.releaseDate) AS isReleaseDateDefined,
    IS_NULL(p.retirementDate) AS isRetirementDateNull,
    IS_DEFINED(p.retirementDate) AS isRetirementDateDefined
FROM
    products p
[
  {
    "isReleaseDateNull": true,
    "isReleaseDateDefined": true,
    "isRetirementDateNull": false,
    "isRetirementDateDefined": false
  }
]

一般的な演算子とその null および undefined 値に関する動作の詳細については、「等値演算子と比較演算子」を参照してください。

JSON での予約キーワードと特殊文字

プロパティは、引用符で囲まれたプロパティの演算子 [] を使用してアクセスすることができます。 たとえば、 SELECT c.grade and SELECT c["grade"] は同等です。 この構文はスペース、特殊文字を含むプロパティや、SQL キーワードや予約語と同じ名前を持つプロパティをエスケープする場合に役立ちます。

たとえば、いくつかの異なる方法でプロパティを参照するクエリを次に示します。

SELECT
    p.manufacturer.name AS dotNotationReference,
    p["manufacturer"]["name"] AS bracketReference,
    p.manufacturer["name"] AS mixedReference
FROM
    products p
[
  {
    "dotNotationReference": "AdventureWorks",
    "bracketReference": "AdventureWorks",
    "mixedReference": "AdventureWorks"
  }
]

JSON 式

クエリ プロジェクションでは、JSON 式と構文がサポートされています。

SELECT {
    "productName": p.name,
    "largeSizeInFeet": p.metadata.sizes.large.feet
}
FROM
    products p
[
  {
    "$1": {
      "productName": "Teapo rainbow surfboard",
      "largeSizeInFeet": 7.66667
    }
  }
]

この例では、SELECT 句によって JSON オブジェクトが作成されます。 サンプルはキーを指定していないので、この句では暗黙的な引数の変数名である $<index-number> が使用されます。

この例では、同じフィールドに明示的に名前を付けます。

SELECT {
    "productName": p.name,
    "largeSizeInFeet": p.metadata.sizes.large.feet
} AS product
FROM
    products p
[
  {
    "product": {
      "productName": "Teapo rainbow surfboard",
      "largeSizeInFeet": 7.66667
    }
  }
]

または、クエリでオブジェクトをフラット化して、冗長なフィールドに名前を付けないようにすることもできます。

SELECT VALUE {
    "productName": p.name,
    "largeSizeInFeet": p.metadata.sizes.large.feet
}
FROM
    products p
[
  {
    "productName": "Teapo rainbow surfboard",
    "largeSizeInFeet": 7.66667
  }
]

エイリアス値

クエリ内の値を明示的にエイリアス化できます。 クエリに同じ名前を持つ 2 つのプロパティがある場合、エイリアス化を使ってプロパティのいずれかまたは両方の名前を変更することで、プロジェクションの結果でこれらを区別できます。

次の例に示すように、エイリアス化に使用する AS キーワードはオプションです。

SELECT
    p.name,
    p.metadata.sku AS modelNumber
FROM
    products p
[
  {
    "name": "Teapo rainbow surfboard",
    "modelNumber": "72109"
  }
]

予約キーワードまたは特殊文字を使用したエイリアス値

スペース、特殊文字、または予約済みのワードが含まれるプロパティ名として値をプロジェクションするためにエイリアス化を使用することはできません。 値のプロジェクションを変更して、プロパティ名にスペースが含まれるようにする必要があるなどの場合は、JSON 式を使用できます。

次に例を示します。

SELECT VALUE {
    "Product's name | ": p.name,
    "Model number => ": p.metadata.sku
}
FROM
    products p
[
  {
    "Product's name | ": "Teapo rainbow surfboard",
    "Model number => ": "72109"
  }
]