Partager via


Aplatissement, échappement et gestion des tableaux JSON

Note

Le service Time Series Insights sera mis hors service le 7 juillet 2024. Envisagez de migrer des environnements existants vers d’autres solutions dès que possible. Pour plus d’informations sur la dépréciation et la migration, consultez notre documentation .

Votre environnement Azure Time Series Insights Gen2 crée dynamiquement les colonnes de vos magasins chauds et froids, en suivant un ensemble particulier de conventions d’affectation de noms. Lorsqu’un événement est ingéré, un ensemble de règles est appliqué aux noms de propriété et de charge utile JSON. Ces opérations comprennent l'échappement de certains caractères spéciaux et la mise à plat des objets JSON imbriqués. Il est important de connaître ces règles afin de comprendre comment la forme de votre JSON influencera la façon dont vos événements sont stockés et interrogés. Consultez le tableau ci-dessous pour obtenir la liste complète des règles. Les exemples A & B montrent également comment vous pouvez traiter efficacement plusieurs séries chronologiques dans un tableau.

Important

  • Passez en revue les règles ci-dessous avant de sélectionner une propriété d’identification de série chronologique et/ou les propriétés de timestamp de votre source d'événements . Si votre ID TS ou votre horodatage se trouve dans un objet imbriqué ou comporte un ou plusieurs des caractères spéciaux mentionnés ci-dessous, il est important de vous assurer que le nom de la propriété que vous fournissez correspond au nom de colonne après que les règles d’ingestion ont été appliquées. Consultez l’exemple B ci-dessous.
Règle Exemple JSON syntaxe d’expression de série chronologique Nom de colonne de propriété dans Parquet
Le type de données Azure Time Series Insights Gen2 est ajouté à la fin de votre nom de colonne en tant que « _<dataType>» "type": "Accumulated Heat" $event.type.String type_string
La source de l'événement et la propriété de l'horodatage seront enregistrées dans Azure Time Series Insights Gen2 sous le nom « timestamp » dans le stockage, et la valeur sera enregistrée au format UTC. Vous pouvez personnaliser la propriété d'horodatage de votre ou vos source(s) de l'événement pour répondre aux besoins de votre solution, mais le nom de la colonne dans le stockage chaud et froid est « timestamp ». D’autres propriétés JSON datetime qui ne sont pas l’horodatage de la source d’événement sont enregistrées avec « _datetime » dans le nom de colonne, comme indiqué dans la règle ci-dessus. "ts": "2020-03-19 14:40:38.318" $event.$ts timestamp
Noms de propriétés JSON qui incluent les caractères spéciaux. [ \ et ' sont échappés à l’aide de [' et '] "id.wasp": "6A3090FD337DE6B" $event['id.wasp'].String ['id.wasp']_string
Dans [' et '] il y a d’autres échappements de guillemets simples et de barres obliques inverses. Une citation unique est écrite en tant que \' et une barre oblique inverse est écrite en tant que \\ "Foo's Law Value": "17.139999389648" $event['Foo\'s Law Value'].Double ['Foo\'s Law Value']_double
Les objets JSON imbriqués sont aplatis avec un point comme séparateur. L’imbrication jusqu’à 10 niveaux est prise en charge. "series": {"value" : 316 } $event.series.value.Long, $event['series']['value'].Long ou $event.series['value'].Long series.value_long
Les tableaux de types primitifs sont stockés en tant que type dynamique "values": [154, 149, 147] Les types dynamiques ne peuvent être récupérés que via l’API GetEvents values_dynamic
Les tableaux contenant des objets ont deux comportements selon le contenu des objets : si les propriétés TS ID(s) ou timestamp se trouvent dans les objets d’un tableau, le tableau est déroulé de sorte que la charge utile JSON initiale génère plusieurs événements. Cela vous permet de regrouper plusieurs événements en une structure JSON. Toutes les propriétés de niveau supérieur associées au tableau seront sauvegardées avec chaque objet déroulé. Si votre ou vos ID TS et horodatage ne sont pas dans le tableau, il est enregistré dans son intégralité en tant que type dynamique. Consultez des exemples A, Bet C ci-dessous
Les tableaux contenant des éléments mixtes ne sont pas aplatis. "values": ["foo", {"bar" : 149}, 147] Les types dynamiques ne peuvent être récupérés que via l’API GetEvents values_dynamic
512 caractères correspond à la limite du nom de propriété JSON. Si le nom dépasse 512 caractères, il est tronqué à 512 et ' _<'hashCode'>' est ajouté. Remarque que cela s’applique également aux noms de propriétés qui ont été concaténés à partir d'objets aplatis, indiquant un chemin d'accès vers un objet imbriqué. "data.items.datapoints.values.telemetry<...continuing to over 512 chars>" : 12.3440495 "$event.data.items.datapoints.values.telemetry<...continuing to include all chars>.Double" data.items.datapoints.values.telemetry<...continuing to 512 chars>_912ec803b2ce49e4a541068d495ab570_double

Comprendre le comportement double des tableaux

Les tableaux d’objets sont stockés entiers ou divisés en plusieurs événements en fonction de la façon dont vous avez modélisé vos données. Cela vous permet d’utiliser un tableau pour traiter les événements par lots et d’éviter de répéter les propriétés de télémétrie définies au niveau de l’objet racine. Le traitement par lots peut être avantageux, car il entraîne moins de messages Event Hubs ou IoT Hub envoyés.

Toutefois, dans certains cas, les tableaux contenant des objets ne sont significatifs que dans le contexte d’autres valeurs. La création de plusieurs événements rend les données sans signification. Pour vous assurer qu’un tableau d’objets est stocké as-is en tant que type dynamique, suivez les instructions de modélisation des données ci-dessous et examinez l’exemple C.

Comment savoir si mon tableau d’objets produit plusieurs événements

Si une ou plusieurs de vos propriétés d’ID Time Series sont imbriquées dans des objets d’un tableau, ou si votre propriété d’horodatage source d’événement est imbriquée, le moteur d’ingestion le fractionne pour créer plusieurs événements. Les noms de propriétés que vous avez fournis pour vos ID TS et/ou horodatage doivent suivre les règles d’aplatissement ci-dessus et indiquent donc la forme de votre JSON. Consultez les exemples ci-dessous, puis consultez le guide pour sélectionner une propriété d’ID de série temporelle.

Exemple A

ID de série chronologique à la racine de l'objet et horodatage imbriqué
ID de série chronologique environnement :"id"
Horodatage de la source de l'événement :"values.time"
charge utile JSON :

[
    {
        "id": "caaae533-1d6c-4f58-9b75-da102bcc2c8c",
        "values": [
            {
                "time": "2020-05-01T00:59:59.000Z",
                "value": 25.6073
            },
            {
                "time": "2020-05-01T01:00:29.000Z",
                "value": 43.9077
            }
        ]
    },
    {
        "id": "1ac87b74-0865-4a07-b512-56602a3a576f",
        "values": [
            {
                "time": "2020-05-01T00:59:59.000Z",
                "value": 0.337288
            },
            {
                "time": "2020-05-01T01:00:29.000Z",
                "value": 4.76562
            }
        ]
    }
]

Résultat dans le fichier Parquet :
La configuration et la charge utile ci-dessus produisent trois colonnes et quatre événements

horodatage id_string valeurs.valeur_double
2020-05-01T00:59:59.000Z caaae533-1d6c-4f58-9b75-da102bcc2c8c 25.6073
2020-05-01T01:00:29.000Z caaae533-1d6c-4f58-9b75-da102bcc2c8c 43.9077
2020-05-01T00:59:59.000Z 1ac87b74-0865-4a07-b512-56602a3a576f 0.337288
2020-05-01T01:00:29.000Z 1ac87b74-0865-4a07-b512-56602a3a576f 4.76562

Exemple B

ID de série chronologique composite avec une propriété imbriquée
Série chronologique d'environnement ID :"plantId" et "telemetry.tagId"
Horodatage de la source d'événement : "timestamp"
charge utile JSON :

[
    {
        "plantId": "9336971",
        "timestamp": "2020-01-22T16:38:09Z",
        "telemetry": [
            {
                "tagId": "100231-A-A6",
                "tagValue": -31.149018
            },
            {
                "tagId": "100231-A-A1",
                "tagValue": 20.560796
            },
            {
                "tagId": "100231-A-A9",
                "tagValue": 177
            },
            {
                "tagId": "100231-A-A8",
                "tagValue": 420
            },
        ]
    },
    {
        "plantId": "9336971",
        "timestamp": "2020-01-22T16:42:14Z",
        "telemetry": [
            {
                "tagId": "103585-A-A7",
                "value": -30.9918
            },
            {
                "tagId": "103585-A-A4",
                "value": 19.960796
            }
        ]
    }
]

Résultat dans le fichier Parquet :
La configuration et la charge utile ci-dessus produisent quatre colonnes et six événements

horodatage plantId_string telemetry.tagId_string télémétrie.valeur_double
2020-01-22T16:38:09Z 9336971 100231-A-A6 -31.149018
2020-01-22T16:38:09Z 9336971 100231-A-A1 20.560796
2020-01-22T16:38:09Z 9336971 100231-A-A9 177
2020-01-22T16:38:09Z 9336971 100231-A-A8 420
2020-01-22T16:42:14Z 9336971 100231-A-A7 -30.9918
2020-01-22T16:42:14Z 9336971 100231-A-A4 19.960796

Exemple C

L’ID de série chronologique et l’horodatage se trouvent à la racine de l’objet
Série chronologique de l'environnement ID: "id"
horodatage de la source d’événements :"timestamp"
charge utile JSON :

{
    "id": "800500054755",
    "timestamp": "2020-11-01T10:00:00.000Z",
    "datapoints": [{
            "value": 120
        },
        {
            "value": 124
        }
    ]
}

Résultat dans le fichier Parquet :
La configuration et la charge utile ci-dessus produisent trois colonnes et un événement

horodatage id_string points_de_données_dynamique
2020-11-01T10:00:00.000Z 800500054755 [{"value": 120},{"value":124}]

Étapes suivantes