Uso di JSON in Azure Cosmos DB for NoSQL

SI APPLICA A: NoSQL

In Azure Cosmos DB for NoSQL, gli elementi vengono archiviati come file JSON. Il sistema di tipi e le espressioni sono quindi limitati all'interazione esclusiva con i tipi JSON. Per altre informazioni, vedere le specifiche JSON.

Verranno riepilogati alcuni aspetti importanti dell'uso di JSON:

  • Gli oggetti JSON iniziano sempre con una parentesi graffa sinistra { e terminano con una parentesi graffa destra }
  • È possibile avere proprietà JSON annidate l'una all'interno dell'altra
  • I valori delle proprietà JSON possono essere matrici
  • I nomi delle proprietà JSON distinguono tra maiuscole e minuscole
  • Il nome di una proprietà JSON può essere qualsiasi valore stringa (inclusi spazi o caratteri diversi da lettere)

Proprietà annidate

È possibile accedere a proprietà JSON annidate usando una funzione di accesso di tipo punto (.). È possibile usare proprietà JSON annidate in una query nello stesso modo in cui può essere usata qualsiasi altra proprietà.

Di seguito è riportato un documento con proprietà JSON annidate:

{
  "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
      }
    }
  }
}

In questo caso, le proprietà sku, colors e sizes sono tutte annidate nella proprietà metadata. Anche la proprietà name viene annidata all'interno della proprietà manufacturer .

Nell'esempio seguente vengono proiettate due proprietà annidate.

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

Usare le matrici

Oltre alle proprietà annidate, il formato JSON supporta anche le matrici. Quando si usano le matrici, è possibile accedere a un elemento specifico all'interno di una matrice facendo riferimento alla relativa posizione.

In questo esempio viene eseguito l'accesso a un elemento di matrice in una posizione specifica.

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"
    ]
  }
]

Nella maggior parte dei casi, tuttavia, quando si usano le matrici si ricorre a una sottoquery o a un self-join.

Ad esempio, ecco una query che restituisce più permutazioni usando i valori di matrice potenziali e un cross join,

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"
  }
]

Come altro esempio, la query può anche usare EXISTS con una sottoquery.

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"
]

Differenza tra null e non definito

Se una proprietà non è definita in un elemento, il suo valore sarà undefined. Una proprietà con il valore null deve essere definita in modo esplicito e le deve essere assegnato un valore null.

Azure Cosmos DB for NoSQL supporta due utili funzioni di sistema di controllo del tipo per le proprietà null e undefined:

  • IS_NULL - controlla se un valore della proprietà è null.
  • IS_DEFINED - controlla se è definito un valore della proprietà o undefined.

Ecco una query di esempio che verifica la presenza di due campi per ogni elemento nel contenitore.

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
  }
]

Per altre informazioni sugli operatori comuni e sul relativo comportamento per i valori di null e undefined , vedere operatori di uguaglianza e confronto.

Parole chiave riservate e caratteri speciali in JSON

È possibile accedere alle proprietà mediante l'operatore della proprietà di delimitazione []. Ad esempio, la sintassi di SELECT c.grade and SELECT c["grade"] sono equivalenti. Questa sintassi risulta utile quando di usano i caratteri di escape per una proprietà che contiene spazi, caratteri speciali o condivide lo stesso nome di una parola chiave SQL o una parola riservata.

Ad esempio, ecco una query che fa riferimento a una proprietà in diversi modi.

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"
  }
]

Espressioni JSON

La proiezione di query supporta espressioni e sintassi JSON.

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

In questo esempio la clausola SELECT crea un oggetto JSON. Poiché l'esempio non fornisce alcuna chiave, la clausola usa il nome della variabile di argomento implicito $<index-number>.

In questo esempio viene specificato in modo esplicito lo stesso campo.

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

In alternativa, la query può appiattire l'oggetto per evitare di denominare un campo ridondante.

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

Valori alias

È possibile eseguire l'aliasing esplicito dei valori nelle query. Nel caso in cui una query avesse due proprietà con lo stesso nome, è necessario usare l'aliasing per rinominare una o entrambe le proprietà, in modo da evitare ambiguità nel risultato proiettato.

Esempi

La parola chiave AS usata per l'aliasing è facoltativa, come illustrato nell'esempio seguente.

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

Valori alias con parole chiave riservate o caratteri speciali

Non è possibile usare l'aliasing per proiettare un valore come nome di proprietà con uno spazio, un carattere speciale o una parola riservata. Se invece si volesse modificare la proiezione di un valore in modo da avere, ad esempio, un nome di proprietà con uno spazio, sarebbe possibile usare un'espressione JSON.

Ecco un esempio:

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