Best way to store object with arbitrary keys? Nested objects?


#1

Hey all. I’ve been looking for a way to do this and it appears to me there isn’t one.

Is there any way to store a simple JSON object with arbitrary keys? For instance, say I want to store a simple caching object on my User object like so:

const PersonSchema = {
  name: 'Person',
  properties: {
    name: 'string',
    arbitraryCache: '???????',
  }
};

const person = {
  name: "John",
  arbitraryCache: {
    cache-435355555: true,
    cache-199349493: true,
    nested-cache-44334: {
       sub-nested-1244: true
    }
  }
}

All I’ve come up with is a string that I serialize back and forth. Is that really the best way to do it? I don’t love it.

More generally, I really like to limit in number Models as much as possible. I don’t like defining a schema for every little object shape. For instance, imagine a game object that you want to store summaryStats on:

const GameSchema = {
  name: 'Game',
  properties: {
    opponent: 'string',
    summaryStats: '???????',
  }
};

const game = {
  opponent: "Manchester",
  summaryStats: {
    passingPercent: 0.34,
    shotsOnGoal: 10
  }
}

Obviously I could create a new schema for summaryStats, but that feels gross. On the other hand I could just move the fields to the top level, but there’s lot of situations where it’s more natural to have it nested, since it creates a natural grouping between the fields. For example, if summaryStats has a ballooning number of fields, I don’t have to worry about them cluttering up the top level Game properties, keeping my top level Game properties nice and clean.


#2

Currently we don’t have a way to provide a “schema less” database - I believe that’s what you need.

If you do with one level, your model could be:

const PersonSchema = {
  name: 'Person',
  properties: {
    name: 'string',
    arbitraryCache: 'Cache[]',
  }
};

const CacheSchema = {
  name: 'Cache',
  properties: {
    key: 'string',
    value: 'string'
  }
};

If you need to store values of different types, you could do a ugly hack like:

const CacheSchema = {
  name: 'Cache',
  properties: {
    key: 'string',
    ivalue: 'int?',
    svalue: 'string?',
    fvalue: 'float?',
    // ... and other types
  }
};

and set all to null except one.

I imagine that https://github.com/realm/realm-js/issues/1610 is what you wish we have :smile:.


#3

Hmm, okay. That seems like a reasonable workaround. And yes, that would be super nice!