JSON(JavaScript Object Notation)을 사용하는 것은 쿼리 언어의 핵심입니다. 항목은 JSON으로 저장되며 모든 쿼리, 식 및 형식은 JSON 데이터에서 작동하도록 설계되었습니다. JSON 자체에 대한 자세한 내용은 공식 JSON 사양을 참조하세요.
다음은 이 컨텍스트에서 JSON에 대해 알아야 할 몇 가지 주요 사항입니다.
- JSON 개체는 항상 .로
{시작하고 끝납니다}. - 속성은 서로 내부에 중첩 될 수 있습니다.
- 속성 값은 배열일 수 있습니다.
- 속성 이름은 대/소문자를 구분합니다.
- 속성 이름은 공백이나 특수 문자가 있는 문자열일 수도 있습니다.
중첩 속성
점 표기법을 사용하여 중첩된 JSON 속성에 액세스할 수 있습니다. 대부분의 프로그래밍 언어에서 속성에 액세스하는 것과 마찬가지로 작동합니다.
다음은 중첩된 JSON을 사용하는 예제 문서입니다.
[
{
"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"
}
}
]
그런 다음 쿼리에서 동일한 중첩 속성을 프로젝스할 수 있습니다.
SELECT
p.name,
p.category,
p.metadata.link
FROM
products p
WHERE
p.name = "Heatker Women's Jacket"
그리고 다음과 같은 예상 출력을 얻을 수 있습니다.
[
{
"name": "Heatker Women's Jacket",
"category": "apparel",
"link": "https://www.adventure-works.com/heatker-women-s-jacket/68719520138.p"
}
]
배열 및 집합
JSON은 배열을 지원하며 쿼리에서 작업할 수 있습니다. 특정 요소에 액세스하려면 배열에서 해당 위치를 사용합니다.
이전 섹션의 동일한 예제를 사용하여 해당 인덱스로 배열의 항목에 액세스할 수 있습니다. 예를 들어 배열의 첫 번째 항목에 액세스하려면 쿼리 언어의 0 배열에 대한 인덱스 시스템 (0부터 시작)이므로 인덱스를 사용합니다.
SELECT
p.name,
p.sizes[0].description AS defaultSize
FROM
products p
WHERE
p.name = "Heatker Women's Jacket"
이 쿼리는 다음 JSON 개체를 생성합니다.
[
{
"name": "Heatker Women's Jacket",
"defaultSize": "Small"
}
]
이제 배열이 더 큰 예제를 살펴보겠습니다.
[
{
"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"
}
]
}
]
종종 하위 쿼리 또는 자체 조인을 사용하여 배열의 모든 요소를 사용하려고 합니다. 예를 들어 각 색을 별도의 행으로 가져옵니다.
SELECT
p.name,
c AS color
FROM
products p
JOIN
c IN p.colors
WHERE
p.name = "Vencon Kid's Coat"
그러면 다음과 같은 JSON 배열이 발생합니다.
[
{
"name": "Vencon Kid's Coat",
"color": "cardinal"
},
{
"name": "Vencon Kid's Coat",
"color": "disco"
}
]
배열에 특정 값이 있는지 확인하려면 키워드 뒤의 필터에서 배열을 WHERE 사용할 수 있습니다. 이 예제에서는 하위 쿼리 를 사용하여 배열의 항목을 필터링합니다.
SELECT VALUE
p.name
FROM
products p
WHERE
EXISTS(SELECT VALUE
c
FROM
c IN p.sizes
WHERE
c.description LIKE "%Large")
이 쿼리는 문자열의 플랫 JSON 배열을 생성합니다. 이 배열에는 예제의 항목이 포함됩니다.
[
...,
"Vencon Kid's Coat"
...
]
마지막으로 여러 속성을 결합하여 배열을 생성할 수 있습니다. 이 예제에서는 여러 속성을 결합하여 배열을 형성합니다 metadata .
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"
]
}
]
반복
쿼리 언어는 원본의 키워드 FROM 를 사용하여 IN JSON 배열을 반복할 수 있습니다.
다음 예제 데이터 집합을 고려합니다.
[
{
"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"
}
]
}
]
이 첫 번째 예제에서는 키워드를 IN 사용하여 각 제품에 대한 속성을 반복 colors 합니다.
SELECT
*
FROM
p IN p.colors
[
"regal-blue",
"rose-bud-cherry",
"starship"
]
절을 사용하여 배열의 개별 항목을 필터링할 WHERE 수도 있습니다. 이 예제에서는 속성이 sizes 필터링됩니다.
SELECT
p.key
FROM
p IN p.sizes
WHERE
p.description LIKE "%Large"
[
{
"key": "l"
},
{
"key": "xl"
},
{
"key": "l"
}
]
동일한 IN 키워드를 사용하여 배열 반복 결과를 집계할 수 있습니다. 이 예제에서 쿼리는 컨테이너의 모든 항목에서 합산된 태그 수를 반환합니다.
SELECT VALUE
COUNT(1)
FROM
p IN p.sizes
비고
반복에 키워드를 IN 사용하는 경우 배열 외부의 속성을 필터링하거나 프로젝션할 수 없습니다. 대신 자체 조인을 사용합니다.
Null 및 정의되지 않은 값
문서에 속성이 없으면 해당 값은 .입니다 undefined. 속성이 있지만 설정된 null경우 명시적으로 설정된 값입니다. 구별 null 은 undefined 쿼리에서 혼동을 일으킬 수 있는 중요한 차이점입니다.
예를 들어 이 JSON 개체는 속성이 정의되지 않았기 때문에 속성의 undefinedsku 값을 갖습니다.
[
{
"name": "Witalica helmet",
"category": "gear",
}
]
속성이 정의되어 있지만 값 null 으로 설정되지 않았으므로 이 JSON 개체의 값은 동일한 속성에 대한 값입니다.
[
{
"name": "Witalica helmet",
"category": "gear",
"sku": null
}
]
이러한 경우를 확인하는 기본 제공 함수가 있습니다.
-
IS_NULL속성이 .인지 확인합니다null. -
IS_DEFINED속성이 있는지 확인합니다(그렇지 않음undefined).
두 가지 모두를 확인할 수 있는 방법은 다음과 같습니다.
SELECT
IS_DEFINED(p.sku) AS isSkuDefined,
IS_NULL(p.sku) AS isSkuDefinedButNull
FROM
products p
대괄호 표기법
대부분의 예제에서는 점 표기법을 사용하여 속성을 지정하지만 대 괄호 표기법을 사용하여 항상 동일한 속성을 지정할 수 있습니다.
중첩된 개체를 속성 값 metadata 으로 사용하는 간단한 개체로 시작해 보겠습니다.
[
{
"name": "Hikomo Sandals",
"metadata": {
"link": "https://www.adventure-works.com/hikomo-sandals/68719519305.p"
}
}
]
해당 개체의 metadata.link 경우 점 및 대괄호 표기법의 조합을 사용하여 세 가지 방법으로 속성을 참조할 수 있습니다.
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"
}
]
팁 (조언)
속성 이름에 공백, 특수 문자 또는 예약어와 일치하는 경우 대괄호 표기법을 사용하여 속성을 지정해야 합니다.
JSON 식
쿼리 결과에서 직접 JSON 개체를 만들 수 있습니다. 이 JSON 배열을 예로 들어 보겠습니다.
[
{
"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
}
]
가장 간단한 구문을 사용하면 NoSQL 쿼리에서 꺾쇠괄호({/}) 및 포함된 JSON 구문을 사용하여 상대적으로 평평한 JSON 개체의 속성 이름에 영향을 줄 수 있습니다.
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"
}
}
]
이전 예제에서는 명시적 이름이 $1 정의되지 않았기 때문에 결과에 유추된 이름이 있었습니다. 다음 예제에서는 결과에 별칭을 사용하여 정의된 명시적 이름이 product 있습니다.
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"
}
}
]
또는 문에서 키워드 SELECT VALUE 를 VALUE 사용하여 결과를 평면화할 수 있습니다.
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"
}
]
더 나아가 JSON 구문을 사용하여 원래 항목에 명시적으로 정의되지 않을 수 있는 배열, 하위 개체 및 기타 JSON 구문을 포함하도록 결과 JSON 개체를 "변형"할 수 있습니다. 이 기술은 클라이언트 애플리케이션이 기본 데이터와 일치하지 않는 특정 스키마의 데이터를 예상하는 경우에 유용합니다.
예를 들어 다음 JSON 스키마를 고려합니다.
{
"$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"
]
}
}
}
이 스키마는 다음 형식으로 구조화된 JSON 개체를 허용합니다.
[
{
"id": "[string]",
"name": "[string]",
"category": {
"department": "[string]",
"section": "[string]"
},
"inventory": {
"stock": [number]
},
"financial": {
"listPrice": [number]
}
}
]
이 NoSQL 쿼리는 이 새 스키마를 준수하도록 원래 개체를 다시 매핑합니다.
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
}
}
]
컨테이너 별칭
기본적으로 키워드 후에 사용되는 용어는 FROM 쿼리의 대상인 컨테이너 를 참조합니다. 용어 자체는 컨테이너의 이름과 일치시킬 필요가 없습니다 .
예를 들어 컨테이너 이름이 지정된 products경우 해당 컨테이너가 쿼리의 대상인 한 이러한 쿼리 중 하나는 제대로 작동하고 모든 쿼리는 컨테이너를 참조 products 합니다.
SELECT
products.id
FROM
products
SELECT
p.id
FROM
p
SELECT
items.id
FROM
items
SELECT
targetContainer.id
FROM
targetContainer
NoSQL 쿼리를 보다 간결하게 만들기 위해 컨테이너 이름을 더 짧은 이름으로 별칭 지정하는 것이 일반적입니다. 별칭 지정은 다음 키워드를 AS 사용하여 수행할 수 있습니다.
SELECT
p.id
FROM
products AS p
쿼리 언어에는 키워드 없이 AS 대상 컨테이너의 참조 바로 후에 별칭을 정의할 수 있는 약식 구문도 있습니다. 이 약식은 키워드를 사용하는 AS 것과 기능적으로 동일합니다.
SELECT
p.id
FROM
products p
속성 별칭
동일한 AS 키워드로 정의된 별칭을 사용하여 결과의 필드 이름을 바꿀 수도 있습니다. 다음 몇 가지 예제에서는 이 샘플 데이터를 고려합니다.
[
{
"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"
}
}
]
이 첫 번째 예제에서는 metadataLink 속성 값에 별칭이 metadata.link 사용됩니다.
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"
}
]
중요합니다
별칭을 사용하여 값을 공백, 특수 문자 또는 예약어와 함께 속성 이름으로 프로젝팅할 수 없습니다. 예를 들어 값의 프로젝션을 공백이 있는 속성 이름으로 변경하려면 JSON 식을 사용해야 합니다.
예를 들면 다음과 같습니다.
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"
}
]
NoSQL 쿼리에 이름이 같은 속성이 두 개 있는 경우 별칭을 사용하여 속성 중 하나 또는 둘 다의 이름을 바꾸면 프로젝트된 결과에서 명확하게 알 수 있습니다.
다음 샘플 데이터를 고려합니다.
[
{
"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"
},
...
]
}
]
비고
이 샘플 데이터 및 쿼리 결과에서 간단히 하기 위해 여러 속성과 값이 제거되었습니다.
이 NoSQL 쿼리는 교차 제품 결과의 속성과 p.tags[].key 속성을 반환 p.sizes[].key 하지만 충돌을 방지하기 위해 각 key 속성의 별칭을 지정합니다.
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"
}
]