Bagikan melalui


Mulai menggunakan JSON - Bahasa kueri di Cosmos DB (di Azure dan Fabric)

Bekerja dengan JavaScript Object Notation (JSON) adalah inti dari bahasa kueri. Item disimpan sebagai JSON, dan semua kueri, ekspresi, dan jenis dirancang untuk bekerja dengan data JSON. Untuk informasi selengkapnya tentang JSON itu sendiri, lihat spesifikasi JSON formal.

Berikut adalah beberapa hal utama yang perlu diketahui tentang JSON dalam konteks ini:

  • Objek JSON selalu dimulai dengan { dan diakhir dengan }.
  • Properti dapat disarangkan di dalam satu sama lain.
  • Nilai properti bisa berupa array.
  • Nama properti peka huruf besar/kecil.
  • Nama properti dapat berupa string apa pun, bahkan dengan spasi atau karakter khusus.

Properti berlapis

Anda dapat mengakses properti JSON berlapis menggunakan notasi titik. Ini berfungsi seperti mengakses properti di sebagian besar bahasa pemrograman.

Berikut adalah contoh dokumen dengan JSON berlapis:

[
  {
    "name": "Heatker Women's Jacket",
    "category": "apparel",
    "slug": "heatker-women-s-jacket",
    "sizes": [
      {
        "key": "s",
        "description": "Small"
      }
    ],
    "metadata": {
      "link": "https://www.adventure-works.com/heatker-women-s-jacket/68719520138.p"
    }
  }
]

Anda kemudian dapat memproyeksikan properti berlapis yang sama dalam kueri Anda:

SELECT
  p.name,
  p.category,
  p.metadata.link
FROM
  products p
WHERE
  p.name = "Heatker Women's Jacket"

Dan Anda akan mendapatkan output yang diharapkan ini:

[
  {
    "name": "Heatker Women's Jacket",
    "category": "apparel",
    "link": "https://www.adventure-works.com/heatker-women-s-jacket/68719520138.p"
  }
]

Array dan set

JSON mendukung array, dan Anda dapat bekerja dengannya dalam kueri Anda. Untuk mengakses elemen tertentu, gunakan posisinya dalam array.

Dengan menggunakan contoh yang sama dari bagian sebelumnya, kita dapat mengakses item dalam array menggunakan indeksnya. Misalnya, jika kita ingin mengakses item pertama dalam array, kita akan menggunakan indeks 0 karena ini adalah sistem indeks berbasis nol untuk array dalam bahasa kueri:

SELECT
  p.name,
  p.sizes[0].description AS defaultSize
FROM
  products p
WHERE
  p.name = "Heatker Women's Jacket"

Kueri ini menghasilkan objek JSON berikut:

[
  {
    "name": "Heatker Women's Jacket",
    "defaultSize": "Small"
  }
]

Sekarang, mari kita pertimbangkan contoh dengan array yang lebih besar:

[
  {
    "name": "Vencon Kid's Coat",
    "category": "apparel",
    "slug": "vencon-kid-s-coat",
    "colors": [
      "cardinal",
      "disco"
    ],
    "sizes": [
      {
        "key": "m",
        "description": "Medium"
      },
      {
        "key": "l",
        "description": "Large"
      },
      {
        "key": "xl",
        "description": "Extra Large"
      }
    ]
  }
]

Seringkali, Anda ingin menggunakan subkueri atau gabungan mandiri untuk bekerja dengan semua elemen dalam array. Misalnya, untuk mendapatkan setiap warna sebagai baris terpisah:

SELECT
  p.name,
  c AS color
FROM
  products p
JOIN
  c IN p.colors
WHERE
  p.name = "Vencon Kid's Coat"

Yang akan menghasilkan array JSON seperti ini:

[
  {
    "name": "Vencon Kid's Coat",
    "color": "cardinal"
  },
  {
    "name": "Vencon Kid's Coat",
    "color": "disco"
  }
]

Untuk memeriksa apakah nilai tertentu ada dalam array, Anda dapat menggunakan array dalam filter setelah WHERE kata kunci. Contoh ini menggunakan subkueri untuk memfilter item array:

SELECT VALUE
  p.name
FROM
  products p
WHERE
  EXISTS(SELECT VALUE
    c
  FROM
    c IN p.sizes
  WHERE
    c.description LIKE "%Large")

Kueri ini menghasilkan array string JSON datar, yang akan menyertakan item dalam contoh:

[
  ...,
  "Vencon Kid's Coat"
  ...
]

Terakhir, Anda dapat membuat array dengan menggabungkan beberapa properti. Dalam contoh ini, beberapa properti digabungkan untuk membentuk metadata array:

SELECT
  p.name,
  [
    p.category,
    p.slug,
    p.metadata.link
  ] AS metadata
FROM
  products p
WHERE
  p.name = "Heatker Women's Jacket"
[
  {
    "name": "Heatker Women's Jacket",
    "metadata": [
      "apparel",
      "heatker-women-s-jacket",
      "https://www.adventure-works.com/heatker-women-s-jacket/68719520138.p"
    ]
  }
]

Iteration

Bahasa kueri mendukung iterasi melalui array JSON menggunakan IN kata kunci di sumbernya FROM .

Pertimbangkan contoh himpunan data ini:

[
  {
    "name": "Pila Swimsuit",
    "colors": [
      "regal-blue",
      "rose-bud-cherry"
    ],
    "sizes": [
      {
        "key": "m",
        "description": "Medium"
      },
      {
        "key": "l",
        "description": "Large"
      },
      {
        "key": "xl",
        "description": "Extra Large"
      }
    ]
  },
  {
    "name": "Makay Bikini",
    "colors": [
      "starship"
    ],
    "sizes": [
      {
        "key": "s",
        "description": "Small"
      },
      {
        "key": "m",
        "description": "Medium"
      },
      {
        "key": "l",
        "description": "Large"
      }
    ]
  }
]

Contoh pertama ini menggunakan IN kata kunci untuk melakukan iterasi atas colors properti untuk setiap produk:

SELECT
  *
FROM
  p IN p.colors
[
  "regal-blue",
  "rose-bud-cherry",
  "starship"
]

Anda juga dapat memfilter entri individual dalam array menggunakan WHERE klausa. Dalam contoh ini, properti difilter sizes :

SELECT
  p.key
FROM
  p IN p.sizes
WHERE
  p.description LIKE "%Large"
[
  {
    "key": "l"
  },
  {
    "key": "xl"
  },
  {
    "key": "l"
  }
]

Dengan menggunakan kata kunci yang sama IN , Anda dapat mengagregasi hasil iterasi array. Dalam contoh ini, kueri mengembalikan jumlah tag yang dijumlahkan di semua item dalam kontainer:

SELECT VALUE
  COUNT(1)
FROM
  p IN p.sizes

Nota

Saat menggunakan kata kunci untuk iterasi IN , Anda tidak dapat memfilter atau memproyeksikan properti apa pun di luar array. Sebagai gantinya, Anda menggunakan gabungan mandiri.

Nilai null dan undefined

Jika properti tidak ada dalam dokumen, nilainya adalah undefined. Jika properti ada tetapi diatur ke null, itu adalah nilai yang ditetapkan secara eksplisit. Perbedaan antara null dan undefined adalah perbedaan penting yang dapat menyebabkan kebingungan dalam kueri.

Misalnya, objek JSON ini akan memiliki nilai undefined untuk sku properti karena properti tidak pernah ditentukan:

[
  {
    "name": "Witalica helmet",
    "category": "gear",
  }
]

Objek JSON ini akan memiliki nilai null untuk properti yang sama karena properti didefinisikan belum diatur dengan nilai:

[
  {
    "name": "Witalica helmet",
    "category": "gear",
    "sku": null
  }
]

Ada fungsi bawaan untuk memeriksa kasus-kasus ini:

  • IS_NULL memeriksa apakah properti adalah null.
  • IS_DEFINED memeriksa apakah properti ada (bukan undefined).

Berikut adalah cara Anda dapat memeriksa keduanya:

SELECT
  IS_DEFINED(p.sku) AS isSkuDefined,
  IS_NULL(p.sku) AS isSkuDefinedButNull
FROM
  products p

Notasi tanda kurung siku

Meskipun sebagian besar contoh menggunakan notasi titik untuk menentukan properti, Anda selalu dapat menentukan properti yang sama menggunakan notasi tanda kurung .

Mari kita mulai dengan objek sederhana dengan objek berlapis sebagai nilai metadata properti:

[
  {
    "name": "Hikomo Sandals",
    "metadata": {
      "link": "https://www.adventure-works.com/hikomo-sandals/68719519305.p"
    }
  }
]

Untuk objek tersebut, kita dapat mereferensikan properti dengan metadata.link tiga cara berbeda menggunakan kombinasi notasi titik dan tanda kurung :

SELECT
  p.metadata.link AS metadataLinkDotNotation,
  p["metadata"]["link"] AS metadataLinkBracketNotation,
  p.metadata["link"] AS metadataLinkMixedNotation
FROM
  products p
WHERE
  p.name = "Hikomo Sandals"
[
  {
    "metadataLinkDotNotation": "https://www.adventure-works.com/hikomo-sandals/68719519305.p",
    "metadataLinkBracketNotation": "https://www.adventure-works.com/hikomo-sandals/68719519305.p",
    "metadataLinkMixedNotation": "https://www.adventure-works.com/hikomo-sandals/68719519305.p"
  }
]

Petunjuk / Saran

Jika nama properti memiliki spasi, karakter khusus, atau cocok dengan kata yang dipesan, Anda harus menggunakan notasi tanda kurung untuk menentukan properti.

Ekspresi JSON

Anda dapat membuat objek JSON secara langsung di hasil kueri Anda. Mari kita mulai dengan array JSON ini sebagai contoh:

[
  {
    "name": "Diannis Watch",
    "category": "apparel",
    "detailCategory": "apparel-accessories-watches",
    "slug": "diannis-watch",
    "sku": "64801",
    "price": 98,
    "quantity": 159
  },
  {
    "name": "Confira Watch",
    "category": "apparel",
    "detailCategory": "apparel-accessories-watches",
    "slug": "confira-watch",
    "sku": "64800",
    "price": 105,
    "quantity": 193
  }
]

Dengan menggunakan sintaks yang paling mudah, Anda dapat memengaruhi nama properti objek JSON yang relatif datar menggunakan tanda kurung sudut ({/}) dan sintaks JSON yang disematkan dalam kueri NoSQL:

SELECT {
  "brandName": p.name,
  "department": p.category
}
FROM
  products p
WHERE
  p.detailCategory = "apparel-accessories-watches"
[
  {
    "$1": {
      "brandName": "Diannis Watch",
      "department": "apparel"
    }
  },
  {
    "$1": {
      "brandName": "Confira Watch",
      "department": "apparel"
    }
  }
]

Dalam contoh sebelumnya, hasilnya memiliki nama $1 yang disimpulkan karena nama eksplisit tidak ditentukan. Dalam contoh berikutnya ini, hasilnya memiliki nama eksplisit yang product ditentukan menggunakan alias:

SELECT {
  "brandName": p.name,
  "department": p.category
} AS product
FROM
  products p
WHERE
  p.detailCategory = "apparel-accessories-watches"
[
  {
    "product": {
      "brandName": "Diannis Watch",
      "department": "apparel"
    }
  },
  {
    "product": {
      "brandName": "Confira Watch",
      "department": "apparel"
    }
  }
]

Atau, hasilnya dapat diratakan menggunakan VALUE kata kunci dalam SELECT VALUE pernyataan:

SELECT VALUE {
  "brandName": p.name,
  "department": p.category
}
FROM
  products p
WHERE
  p.detailCategory = "apparel-accessories-watches"
[
  {
    "brandName": "Diannis Watch",
    "department": "apparel"
  },
  {
    "brandName": "Confira Watch",
    "department": "apparel"
  }
]

Lebih jauh lagi, Anda dapat menggunakan sintaks JSON untuk "membentuk ulang" objek JSON hasil untuk menyertakan array, subobjek, dan konstruksi JSON lainnya yang mungkin tidak ditentukan secara eksplisit dalam item asli. Teknik ini berguna jika aplikasi klien mengharapkan data dalam skema tertentu yang tidak cocok dengan data yang mendasar.

Pertimbangkan skema JSON ini, misalnya:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "required": [
    "id",
    "category",
    "financial"
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "category": {
      "type": "object",
      "properties": {
        "department": {
          "type": "string"
        },
        "section": {
          "type": "string"
        }
      },
      "required": [
        "department"
      ]
    },
    "inventory": {
      "type": "object",
      "properties": {
        "stock": {
          "type": "number"
        }
      }
    },
    "financial": {
      "type": "object",
      "properties": {
        "listPrice": {
          "type": "number"
        }
      },
      "required": [
        "listPrice"
      ]
    }
  }
}

Skema tersebut akan memungkinkan objek JSON yang terstruktur dalam format ini:

[
  {
    "id": "[string]",
    "name": "[string]",
    "category": {
      "department": "[string]",
      "section": "[string]"
    },
    "inventory": {
      "stock": [number]
    },
    "financial": {
      "listPrice": [number]
    }
  }
]

Kueri NoSQL ini memetakan ulang objek asli agar sesuai dengan skema baru ini:

SELECT VALUE {
  "id": p.sku,
  "name": p.name,
  "category": {
    "department": p.category,
    "section": p.detailCategory
  },
  "inventory": {
    "stock": p.quantity
  },
  "financial": {
    "listPrice": p.price
  }
}
FROM
  products p
WHERE
  p.detailCategory = "apparel-accessories-watches"
[
  {
    "id": "64801",
    "name": "Diannis Watch",
    "category": {
      "department": "apparel",
      "section": "apparel-accessories-watches"
    },
    "inventory": {
      "stock": 159
    },
    "financial": {
      "listPrice": 98
    }
  },
  {
    "id": "64800",
    "name": "Confira Watch",
    "category": {
      "department": "apparel",
      "section": "apparel-accessories-watches"
    },
    "inventory": {
      "stock": 193
    },
    "financial": {
      "listPrice": 105
    }
  }
]

Alias kontainer

Secara default, istilah yang digunakan setelah FROM kata kunci mereferensikan kontainer yang menjadi target kueri. Istilah itu sendiri TIDAK diperlukan untuk mencocokkan nama kontainer.

Misalnya, jika kontainer diberi nama products, salah satu kueri ini berfungsi dengan baik dan semua mereferensikan products kontainer selama kontainer tersebut adalah target kueri:

SELECT
  products.id
FROM
  products
SELECT
  p.id
FROM
  p
SELECT
  items.id
FROM
  items
SELECT
  targetContainer.id
FROM
  targetContainer

Untuk membuat kueri NoSQL Anda lebih ringkas, alias nama kontainer dengan nama yang lebih pendek. Alias dapat dilakukan menggunakan AS kata kunci:

SELECT
  p.id
FROM
  products AS p

Bahasa kueri juga memiliki sintaks singkat di mana alias dapat didefinisikan segera setelah referensi kontainer target tanpa AS kata kunci. Singkatan ini secara fungsional setara dengan menggunakan AS kata kunci:

SELECT
  p.id
FROM
  products p

Alias properti

Anda juga dapat mengganti nama bidang dalam hasil Anda menggunakan alias yang ditentukan dengan kata kunci yang sama AS . Untuk beberapa contoh berikutnya, pertimbangkan data sampel ini:

[
  {
    "name": "Oceabelle Scarf",
    "detailCategory": "apparel-accessories-scarfs-and-socks",
    "metadata": {
      "link": "https://www.adventure-works.com/oceabelle-scarf/68719522190.p"
    }
  },
  {
    "name": "Shinity Socks",
    "detailCategory": "apparel-accessories-scarfs-and-socks",
    "metadata": {
      "link": "https://www.adventure-works.com/shinity-socks/68719522161.p"
    }
  },
  {
    "name": "Horric Socks",
    "detailCategory": "apparel-accessories-scarfs-and-socks",
    "metadata": {
      "link": "https://www.adventure-works.com/horric-socks/68719522177.p"
    }
  }
]

Dalam contoh pertama ini, metadataLink alias digunakan untuk metadata.link nilai properti:

SELECT
  p.name,
  p.metadata.link AS metadataLink
FROM
  products p
[
  {
    "name": "Oceabelle Scarf",
    "metadataLink": "https://www.adventure-works.com/oceabelle-scarf/68719522190.p"
  },
  {
    "name": "Shinity Socks",
    "metadataLink": "https://www.adventure-works.com/shinity-socks/68719522161.p"
  },
  {
    "name": "Horric Socks",
    "metadataLink": "https://www.adventure-works.com/horric-socks/68719522177.p"
  }
]

Penting

Anda tidak dapat menggunakan aliasing untuk memproyeikan nilai sebagai nama properti dengan spasi, karakter khusus, atau kata yang dipesan. Jika Anda ingin mengubah proyeksi nilai menjadi, misalnya, memiliki nama properti dengan spasi, Anda harus menggunakan ekspresi JSON.

Contohnya,

SELECT VALUE {
  "product name": p.name,
  "from": p.metadata.link,
  "detail/category": p.detailCategory
}
FROM
  products p
WHERE
  p.detailCategory = "apparel-accessories-scarfs-and-socks"
[
  {
    "product name": "Oceabelle Scarf",
    "from": "https://www.adventure-works.com/oceabelle-scarf/68719522190.p",
    "detail/category": "apparel-accessories-scarfs-and-socks"
  },
  {
    "product name": "Shinity Socks",
    "from": "https://www.adventure-works.com/shinity-socks/68719522161.p",
    "detail/category": "apparel-accessories-scarfs-and-socks"
  },
  {
    "product name": "Horric Socks",
    "from": "https://www.adventure-works.com/horric-socks/68719522177.p",
    "detail/category": "apparel-accessories-scarfs-and-socks"
  }
]

Jika kueri NoSQL memiliki dua properti dengan nama yang sama, gunakan alias untuk mengganti nama salah satu atau kedua properti sehingga tidak ambigu dalam hasil yang diproyeksikan.

Pertimbangkan data sampel ini:

[
  {
    "name": "Oceabelle Scarf",
    "detailCategory": "apparel-accessories-scarfs-and-socks",
    "sizes": [
      {
        "key": "s"
      },
      ...
    ],
    "tags": [
      ...
    ]
  },
  {
    "name": "Shinity Socks",
    "detailCategory": "apparel-accessories-scarfs-and-socks",
    "sizes": [
      ...
      {
        "key": "10"
      },
      ...
    ],
    "tags": [
      ...
      {
        "key": "length"
      }
    ]
  },
  {
    "name": "Horric Socks",
    "detailCategory": "apparel-accessories-scarfs-and-socks",
    "sizes": [
      ...
      {
        "key": "7"
      },
      ...
    ],
    "tags": [
      {
        "key": "fabric"
      },
      ...
    ]
  }
]

Nota

Dalam data sampel ini dan hasil kueri, beberapa properti dan nilai dihapus untuk brevity.

Kueri NoSQL ini mengembalikan p.sizes[].key properti dan p.tags[].key dalam hasil lintas produk tetapi akan alias setiap key properti untuk menghindari tabrakan:

SELECT
  p.name,
  s.key AS sizeKey,
  t.key AS tagKey
FROM
  products p
JOIN
  s IN p.sizes
JOIN
  t in p.tags
WHERE
  p.detailCategory = "apparel-accessories-scarfs-and-socks"
[
  {
    "name": "Oceabelle Scarf",
    "sizeKey": "s",
    "tagKey": "fabric"
  },
  ...
  {
    "name": "Shinity Socks",
    "sizeKey": "10",
    "tagKey": "length"
  },
  ...
  {
    "name": "Horric Socks",
    "sizeKey": "7",
    "tagKey": "fabric"
  }
]