Freigeben über


Erste Schritte mit JSON – Abfragesprache in Cosmos DB (in Azure und Fabric)

Die Arbeit mit JavaScript Object Notation (JSON) ist das Herzstück der Abfragesprache. Elemente werden als JSON gespeichert, und alle Abfragen, Ausdrücke und Typen sind für die Verwendung von JSON-Daten konzipiert. Weitere Informationen zu JSON selbst finden Sie in der formalen JSON-Spezifikation.

Im Folgenden sind einige wichtige Informationen zu JSON in diesem Kontext aufgeführt:

  • JSON-Objekte beginnen immer mit { und enden mit }.
  • Eigenschaften können miteinander verschachtelt werden.
  • Eigenschaftswerte können Arrays sein.
  • Bei Eigenschaftennamen wird zwischen Groß- und Kleinschreibung unterschieden.
  • Eigenschaftsnamen können eine beliebige Zeichenfolge sein, auch mit Leerzeichen oder Sonderzeichen.

Verschachtelte Eigenschaften

Sie können mithilfe der Punktnotation auf geschachtelte JSON-Eigenschaften zugreifen. Dies funktioniert genauso wie der Zugriff auf Eigenschaften in den meisten Programmiersprachen.

Hier ist ein Beispieldokument mit geschachtelter 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"
    }
  }
]

Anschließend können Sie die gleichen geschachtelten Eigenschaften in Ihren Abfragen projizieren:

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

Und Sie würden diese erwartete Ausgabe erhalten:

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

Arrays und Sets

JSON unterstützt Arrays, und Sie können mit ihnen in Ihren Abfragen arbeiten. Verwenden Sie die Position des Arrays, um auf ein bestimmtes Element zuzugreifen.

Mit demselben Beispiel aus dem vorherigen Abschnitt können wir mithilfe des Indexes auf ein Element im Array zugreifen. Wenn wir beispielsweise auf das erste Element im Array zugreifen möchten, verwenden wir einen Index, da 0 es sich um ein nullbasiertes Indexsystem für Arrays in der Abfragesprache handelt:

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

Diese Abfrage führt zum folgenden JSON-Objekt:

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

Betrachten wir nun ein Beispiel mit einem größeren Array:

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

Häufig möchten Sie eine Unterabfrage oder eine Selbstverknnung verwenden, um mit allen Elementen in einem Array zu arbeiten. So rufen Sie beispielsweise jede Farbe als separate Zeile ab:

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

Dies würde dazu führen, dass ein JSON-Array wie folgt aussieht:

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

Um zu überprüfen, ob ein bestimmter Wert in einem Array vorhanden ist, können Sie das Array im Filter nach dem WHERE Schlüsselwort verwenden. In diesem Beispiel wird eine Unterabfrage verwendet, um die Elemente des Arrays zu filtern:

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

Diese Abfrage führt zu einem flachen JSON-Array mit Zeichenfolgen, das das Element in das Beispiel einschließen würde:

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

Schließlich können Sie Arrays erstellen, indem Sie mehrere Eigenschaften kombinieren. In diesem Beispiel werden mehrere Eigenschaften kombiniert, um ein metadata Array zu bilden:

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

Die Abfragesprache unterstützt die Iteration über JSON-Arrays mithilfe des IN Schlüsselworts in der FROM Quelle.

Betrachten Sie dieses Beispieldatensatz:

[
  {
    "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 diesem ersten Beispiel wird das IN Schlüsselwort verwendet, um die Iteration der colors Eigenschaft für jedes Produkt durchzuführen:

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

Sie können auch einzelne Einträge im Array mithilfe der WHERE Klausel filtern. In diesem Beispiel wird die sizes Eigenschaft gefiltert:

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

Mit demselben IN Schlüsselwort können Sie das Ergebnis einer Arrayiteration aggregieren. In diesem Beispiel gibt die Abfrage die Anzahl der Tags zurück, die über alle Elemente im Container addiert werden:

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

Hinweis

Wenn Sie das IN Schlüsselwort für die Iteration verwenden, können Sie keine Eigenschaften außerhalb des Arrays filtern oder projizieren. Stattdessen verwenden Sie Selbstverknnungen.

Null- und nicht definierte Werte

Wenn eine Eigenschaft in einem Dokument nicht vorhanden ist, lautet undefinedder Wert . Wenn eine Eigenschaft vorhanden, aber auf null" festgelegt" festgelegt ist, ist dies ein explizit festgelegter Wert. Der Unterschied zwischen null und undefined ist ein wichtiger Unterschied, der zu Verwirrung bei Abfragen führen kann.

Beispielsweise hätte dieses JSON-Objekt einen Wert undefined für die sku Eigenschaft, da die Eigenschaft nie definiert wurde:

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

Dieses JSON-Objekt hätte einen Wert null für dieselbe Eigenschaft, da die Eigenschaft noch nicht mit einem Wert festgelegt wurde:

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

Es gibt integrierte Funktionen, die auf diese Fälle überprüft werden können:

  • IS_NULL überprüft, ob eine Eigenschaft ist null.
  • IS_DEFINED überprüft, ob eine Eigenschaft vorhanden ist (ist nicht undefined).

So können Sie beides überprüfen:

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

Klammernnotation

Die meisten Beispiele verwenden die Punktnotation zum Angeben von Eigenschaften, Sie können jedoch immer die gleichen Eigenschaften mit der Klammernotation angeben.

Beginnen wir mit einem einfachen Objekt mit einem geschachtelten Objekt als Wert der metadata Eigenschaft:

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

Für dieses Objekt können wir auf drei verschiedene Arten auf die metadata.link Eigenschaft verweisen, indem wir Kombinationen aus Punkt - und Klammernotation verwenden:

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

Tipp

Wenn ein Eigenschaftsname Leerzeichen, Sonderzeichen oder einem reservierten Wort entspricht, müssen Sie die Klammernotation verwenden, um die Eigenschaft anzugeben.

JSON-Ausdrücke

Sie können JSON-Objekte direkt in Den Abfrageergebnissen erstellen. Beginnen wir mit diesem JSON-Array als Beispiel:

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

Mithilfe der einfachsten Syntax können Sie die Eigenschaftsnamen eines relativ flachen JSON-Objekts mithilfe von Winkelklammern ({/}) und der eingebetteten JSON-Syntax in einer NoSQL-Abfrage beeinflussen:

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

Im vorherigen Beispiel hatte das Ergebnis einen abgeleiteten Namen, weil $1 kein expliziter Name definiert wurde. Im nächsten Beispiel weist das Ergebnis einen expliziten Namen auf, der product mithilfe eines Alias definiert wurde:

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

Alternativ kann das Ergebnis mithilfe des VALUE Schlüsselworts in einer SELECT VALUE Anweisung abgeflacht werden:

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

Noch weiter können Sie die JSON-Syntax verwenden, um das JSON-Ergebnisobjekt zu "neu gestalten", um Arrays, Unterobjekte und andere JSON-Konstrukte einzuschließen, die möglicherweise nicht explizit im ursprünglichen Element definiert werden. Diese Technik ist nützlich, wenn die Clientanwendung Daten in einem bestimmten Schema erwartet, das nicht mit zugrunde liegenden Daten übereinstimmt.

Betrachten Sie dieses JSON-Schema, z. B.:

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

Dieses Schema würde ein JSON-Objekt in diesem Format strukturieren:

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

Mit dieser NoSQL-Abfrage wird das ursprüngliche Objekt[s] neu zugeordnet, damit es mit diesem neuen Schema kompatibel ist:

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

Containeraliasen

Standardmäßig verweist der nach dem FROM Schlüsselwort verwendete Begriff auf den Container , der das Ziel der Abfrage ist. Der Begriff selbst ist NICHT erforderlich, um dem Namen des Containers zu entsprechen.

Wenn der Container beispielsweise benannt productsist, funktionieren alle diese Abfragen einwandfrei, und alle verweisen auf den products Container, solange dieser Container das Ziel der Abfrage ist:

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

Um Ihre NoSQL-Abfrage präziser zu gestalten, ist es üblich, den Containernamen mit einem kürzeren Namen zu aliasen. Aliasing kann mithilfe des AS Schlüsselworts erfolgen:

SELECT
  p.id
FROM
  products AS p

Die Abfragesprache verfügt auch über eine Kurzhandsyntax, bei der der Alias unmittelbar nach dem Verweis des Zielcontainers ohne das AS Schlüsselwort definiert werden kann. Diese Kurzform entspricht funktional der Verwendung des AS Schlüsselworts:

SELECT
  p.id
FROM
  products p

Eigenschaftenaliasen

Sie können Felder in Ihren Ergebnissen auch umbenennen, indem Sie Aliase definieren, die mit demselben AS Schlüsselwort definiert sind. Betrachten Sie diese Beispieldaten für die nächsten Beispiele:

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

In diesem ersten Beispiel wird der metadataLink Alias für den Wert der metadata.link Eigenschaft verwendet:

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

Von Bedeutung

Sie können aliase nicht verwenden, um einen Wert als Eigenschaftsnamen mit einem Leerzeichen, Sonderzeichen oder reservierten Wort zu projizieren. Wenn Sie beispielsweise die Projektion eines Werts in einen Eigenschaftsnamen mit einem Leerzeichen ändern möchten, müssen Sie einen JSON-Ausdruck verwenden.

Beispiel:

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

Wenn eine NoSQL-Abfrage zwei Eigenschaften mit demselben Namen aufweist, verwenden Sie Aliase, um eine oder beide Eigenschaften umzubenennen, sodass sie im projizierten Ergebnis eindeutig sind.

Betrachten Sie diese Beispieldaten:

[
  {
    "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"
      },
      ...
    ]
  }
]

Hinweis

In diesen Beispieldaten und dem Abfrageergebnis wurden mehrere Eigenschaften und Werte aus Platzgründen entfernt.

Diese NoSQL-Abfrage gibt die p.sizes[].key Eigenschaften und p.tags[].key Eigenschaften im produktübergreifenden Ergebnis zurück, aliast jedoch jede key Eigenschaft, um Kollisionen zu vermeiden:

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