5

I'm creating an index file in JSON, which I'm using as a sort-of-database index for a javascript application I'm working on.

My index will look like this:

{
"_id": "acomplex_indices.json",
"indexAB": {
    "title": {
        "Shawshank Redemption": [
            "0"
        ],
        "Godfather": [
            "1"
        ],
        "Godfather 2": [
            "2"
        ],
        "Pulp Fiction": [
            "3"
        ],
        "The Good, The Bad and The Ugly": [
            "4"
        ],
        "12 Angry Men": [
            "5"
        ],
        "The Dark Knight": [
            "6"
        ],
        "Schindlers List": [
            "7"
        ],
        "Lord of the Rings - Return of the King": [
            "8"
        ],
        "Fight Club": [
            "9"
        ],
        "Star Wars Episode V": [
            "10"
        ],
        "Lord Of the Rings - Fellowship of the Ring": [
            "11"
        ],
        "One flew over the Cuckoo's Nest": [
            "12"
        ],
        "Inception": [
            "13"
        ],
        "Godfellas": [
            "14"
        ]
    },
    "year": {
        "1994": [
            "0",
            "3"
        ],
        "1972": [
            "1"
        ],
        "1974": [
            "2"
        ],
        "1966": [
            "4"
        ],
        "1957": [
            "5"
        ],
        "2008": [
            "6"
        ],
        "1993": [
            "7"
        ],
        "2003": [
            "8"
        ],
        "1999": [
            "9"
        ],
        "1980": [
            "10"
        ],
        "2001": [
            "11"
        ],
        "1975": [
            "12"
        ],
        "2010": [
            "13"
        ],
        "1990": [
            "14"
        ]
    }
}
}

So for every keyword (like Pulp Fiction), I'm storing the matching document-id(s).

My problem is with integers/numbers/non-string data, like the release year in the above example. This is stored as a string, while I had hoped it would be stored as a number.

I'm creating the index entries like this:

// indices = the current index file
// doc = the document to update the index with
// priv.indices = all indices defined for this application instance
// priv.indices.fields = index fields e.g. "year", "director", "title"
// priv.indices.name = name of this index

priv.updateIndices = function (indices, doc) {
var i, j, index, value, label, key, l = priv.indices.length;

// loop all indices to add document
for (i = 0; i < l; i += 1) {
  index = {};
  index.reference = priv.indices[i];
  index.reference_size = index.reference.fields.length;
  index.current = indices[index.reference.name];

  for (j = 0; j < index.reference_size; j += 1) {
    label = index.reference.fields[j];    // like "year"
    value = doc[label];                   // like 1985

    // if document has a label field (e.g. doc.year = 1985)
    if (value !== undefined) {

      // check if the index file already contains an entry for 1985
      index.current_size = priv.getObjectSize(index.current[label]);

      if (index.current_size > 0) {
        // check if the document id is already in the index
        // in case the data is updated (e.g. change 1982 to 1985)
        key = priv.searchIndexByValue(
          index.current[label],
          doc._id,
          "key"
        );
        if (!!key) {
          delete index.current[label][key];
        }
      }
      // create a new array if 1985 is not in the index yet
      if (index.current[label][value] === undefined) {
        index.current[label][value] = [];
      }
      // add the document id to an existing entry
      index.current[label][value].push(doc._id);
    }
  }
}
return indices;

};

This works fine, except that fields I want to store as non-strings (integers, numbers or datetime), like the year in the above example end up as strings in my index.

Question:
Is it at all possible to store "non-string" types in a JSON document? If so, can I also store the key of a key/value pair as a "non-string" element.

If not, would I have to add a parameter to my index definitions declaring the type of each key in order to modify the key-string when I run into it or is there a better way to do it?

Thanks!

frequent
  • 24,965
  • 53
  • 166
  • 316
  • 1
    according to the [json spec](http://json.org/), you can have a number anywhere you could have a `value`. So the key of an object *must* be a string, but the value can be a number. Also any of the values in an array can be a number. – jbabey Feb 04 '13 at 13:13

3 Answers3

10

Is it at all possible to store "non-string" types in a JSON document?

Yes. The value of a property can be a string, number, boolean, object, array or null (undefined is a notable exception - it's a native JavaScript type but it's not a valid JSON value).

Can I also store the key of a key/value pair as a "non-string" element?

No. The key name must always be a string. However, that doesn't mean you can't parse that string into some other JavaScript type. For example, if you have a string but need a number, you can use the parseInt function, or the unary + operator.

See the JSON grammar for more detail.

James Allardice
  • 156,021
  • 21
  • 318
  • 304
1

no you can't, in JSON keys are strings.

the best you can do is storing string representations of those keys, wether integer or objects(more complicated, you have to build a serialization function).

If you want to use only consecutive integers keys starting from 0, then you can use arrays.

BiAiB
  • 10,011
  • 7
  • 39
  • 55
1

According to the json spec, you can have a number anywhere you could have a value. So the key of an object must be a string, but the value can be a number. Also any of the values in an array can be a number.

The spec is beside the point though; I believe the issue is this line:

index.current[label][value].push(doc._id);

When you read doc._id, that is a string. If you want to store it in the JSON as a number, you need to cast it:

index.current[label][value].push(parseInt(doc._id, 10));

Also note that having just numbers as IDs is not valid HTML.

Community
  • 1
  • 1
jbabey
  • 42,963
  • 11
  • 66
  • 94