Gianluca Ghettini
Gianluca Ghettini

Reputation: 11648

How can I improve my JSON schema?

I have this JSON here:

  [{
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ -2.449212707644754, 2.3458776596, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 1.449212707644754, 2.3458776596, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, 2.3458776596, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, 2.3458776596, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, 2.3458776596, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, 2.3458776596, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, 2.3458776596, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, 2.3458776596, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ -5.449212707644754, 2.3458776596, -1.452433 ]
  }]

which represents a list of points in a graph. In this case we have three points for a given timestamp so this JSON describes three plots (three channels).

This holds for normal channel (i.e. a list of simple float values). So far so good.

Unfortunately, in some cases we have the so called "minmax" channels in which each point is represented as a pair of float!

Let's take the last example and replace the middle channel (the second one) as a "minmax" channel. The problem here is that I don't know how to JSON-ize the pair of float for that "minmax" channel without ambiguity.

  [{
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ -2.449212707644754, ???, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 1.449212707644754, ???, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, ???, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, ???, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, ???, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, ???, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, ???, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ 0.449212707644754, ???, 1.452433 ]
  },
  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ -5.449212707644754, ???, -1.452433 ]
  }]

What's the best way to do it? Can I have unnamed arrays inside other arrays? And what about deserializing such JSON in a Javascript object?

Upvotes: 0

Views: 73

Answers (3)

bhspencer
bhspencer

Reputation: 13570

Make your channel values an array of objects. This way you can name the properties of those objects rather than rely on their position to indicate their meaning. e.g.

{
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [
        { 
            value: -2.449212707644754
        },
        { 
            min: -2.449212707644754,
            max: 4.678432425151,
        },
        { 
            value: 1.452433
        }
    ]
}

Regarding JSON data size, most web servers will allow you to enable compression of HTTP responses and browsers will decompress automatically. This is super easy to enable on the server side. Compressed JSON is just as small as a binary protocol such as Google Protocol Buffers. In this case there will be lots of redundancy in the JSON so it should zip up extremely well. You could also make the property names single characters as well. e.g. v for value, n for min and x for max.

{
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [
        { 
            v: -2.449212707644754
        },
        { 
            n: -2.449212707644754,
            x: 4.678432425151,
        },
        { 
            v: 1.452433
        }
    ]
}

Upvotes: 0

damgad
damgad

Reputation: 1446

If channels have some meaning, you could also consider following schema with first, second and third names replaced to better describe the channel.

{
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "Channels": {
        "first": {
            "value": -5.449212707644754
        },
        "second": {
            "min": 0.312,
            "max": 1.2312321
        },
        "third": {
            "value": -1.452433
        }
    }
}

Adventage of that solution is better readability. It's obvious what mean min and max. If you use nested arrays, no one will know that it's a "minmax" channel

Upvotes: 0

Nidhoegger
Nidhoegger

Reputation: 5232

You could nest an array in this part, like so:

Without minimax:

  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ [0.449212707644754], [1.11111], [1.452433] ]
  },

With minimax:

  {
    "HistoryId": "bf39d7cfca8536b3e00e5355dff25a97715bc439a5c73d41d10a9eb0c45f2e68",
    "DateTime": "2014-05-13T09:24:49",
    "ChannelsValues": [ [0.449212707644754], [1.11111, 1.63245345], [1.452433] ]
  },

Then on parsing, you would only have to check how many array elements the second channel has, that way you can determine if its minimax or not. Of course it works exactly the same with channel one and three.

When typed, an array is represented as open and closed brackets: []which may contain a comma-separated list of values[ "a", "b", "c" ]. These values can be any JSON data type: string, number,boolean, object, array, null. Source: https://www.json.com/json-array

Upvotes: 1

Related Questions