How can Couchbase deal with dynamic data models?
I have a database app right now using SQLite and FMDB on iOS and Mac which lets the user define their own forms to capture whatever kind of data they need. I have over 20 different types of data they can capture including Text, Notes, Numbers, Audio Recordings, Photos, and relationships to other forms.
The way my database is organized is I have a Form object which has an array of Field objects. A separate object holds the records. Each record can contain one or more value indexed by the field_id. So that way a user can decide at any moment to add or remove any field from their form or add as many forms that they'd like. It's very flexible.
I'm currently trying to convert over from FMDB / SQLite to CouchbaseLite in order to take advantage of your awesome built-in sync mechanism.
My question is, what is the best way to structure my Couch Document given the fact that I don't really have a fixed schema from a user's perspective. So right now if I want to get a value, I first need to know the form, the record, and the field. All those 3 things will give me the value. I currently store the values in a separate table indexed by form, record, and field. But I find that's very inefficient space and query wise. I was hoping that perhaps using CouchbaseLite (and server) would help me to speed that up and also have sync support.
Any pointers would be greatly appreciated.
Oh, and I have done some initial work on writing a conversion routine, so this is what the JSON looks like for an individual record:
{
"01347DCD-9BE7-41AB-8B46-6588F6421FC8": "Brendan Duddridge",
"14AF6617-A724-4C77-A84B-F33496D68519": "H0H 0H0",
"22F6AE40-08A8-43E2-BE0E-E9AD86252C3D": "Duddridge",
"2879D926-CE7A-44EC-BD8D-610E6AB505E0": "Brendan",
"5FF7E2CB-700D-49D5-8723-04DDA79B8AD4": "Calgary",
"6C15F333-DCFA-43DC-B0A8-61EC02085C17": "Canada",
"6D82B007-62AB-46A0-B5DE-ACCBBA154CCF": "",
"6DAD7D2D-EFF8-44F5-9322-A95DE3C8E3D2": "Tap Zapp Software Inc.",
"91EEC079-3DA3-4F45-B8D2-42F9D3591B43": "10",
"BBEA5EF1-1AB9-4CE0-8F11-9C23D0BE7ADE": "123 Tap Zapp Place",
"DB647E15-9006-4DA5-8E29-F076657FA72C": "AB",
"dateCreated": "2014-09-28 09:04:30 +0000",
"dateModified": "2015-04-11 05:24:33 +0000",
"formId": "715BAC6E-6D39-4B65-9E4E-ECDCD45F591D",
"hasAlarm": "0",
"isFavourite": "0",
"primaryKey": "45A98F59-82CF-45E9-BAF9-ED7B496F960F",
"sortOrder": "0",
"type": "FormEntry"
}
Those UUIDs to the left of the values are the Field UUIDs which are actually the Document IDs for the Field type entries in the CouchbaseLite database.
What I'm not sure about is how to build views on this kind of data in order to efficiently query it. Right now in my current model I have each value in its own row in the database. I have an FTS database I use to search quickly. It's pretty quick, but the problem is the size of the database is enormous for the amount of data stored because for each value I store a bunch of other meta data and essentially each value is stored in the main table as well as the FTS index table so it can get pretty huge.
I also need to be able to query by any of the fields in the database in a variety of ways. For example, date ranges, numeric ranges, full text queries, empty values, not empty values, possibly all combined. An example might be, give me a list of movies with a rating > 3 that have the word "Terminator" OR "Hunger" in the movie title. Or another might be a search for all the records that do or don't have an "I saw this movie" checkbox selected.
Any help would be greatly appreciated.
Thanks,
Brendan