Documents
Ditto is a NoSQL database, that can store JSON-like Documents organized by Collections. However, unlike JSON, Ditto allows you to apply updates to the document which will be synchronized with any other copy on other devices. In addition, it supports additional data types.
Collections
You can think of a collection as a table in a traditional database. However, unlike traditional SQL databases, Ditto's collections are far simpler and more flexible. A collection is merely referenced by its string value, there is no need to "create" a collection. Collections are only referenced once there is at least one document that is related to a collection name.
While it is typically common for all documents in a collection to have the same structure, it is not a technical requirement. For example, all documents referencing cars can go in the "cars" collection and boat documents in the "boats" collection. You can create any number of collections that best represent your data model.
To get a reference to a collection:
let carsCollection = ditto.store["cars"]// orlet carsCollection = ditto.store.collection("cars")
Documents
A Ditto document is a schema flexible unit of data in Ditto. If collections are similar to tables, then a document is similar to a row. A document, at its highest level, is a map that can contain arbitrarily nested keys and values. Each document has a primary key, often referred to as an id.
Primary Key _id
Each document must have a unique identifier called the _id
. This is
the primary key of the document and is not optional. As an example, let's create
a document in the people
collection.
do { // upsert JSON-compatible data into Ditto let docID = try ditto.store["people"].upsert([ "name": "Susan", "age": 31 ])} catch { //handle error print(error)}
The _id
parameter is optional when you create a document. If you do not supply a
document _id
, Ditto will automatically generate a random, unique string and
use that as the document's _id
.
Usage
Supplying the identifier for a document
You can also supply your own unique identifier when creating a document. You do this by passing _id
as a parameter to the upsert
function:
do { // upsert JSON-compatible data into Ditto let docID = try ditto.store["people"].upsert([ "_id": "abc123", "name": "Susan", "age": 31 ]) XCTAssertEqual(docID, "abc123")} catch { //handle error print(error)}
Composite identifiers
Ditto's _id
field can be a string or a map of values. For example, we may have
a person document with a unique identifier with two parts:
- a string
userId
; and - an integer
workId
.
We can insert each document as a composite key as a nested
map structure under the _id
field like so.
do { let docID = try ditto.store["people"].upsert([ "_id": [ "userId": "456abc", "workId": 789 ] as [String : Any], "name": "Susan", "age": 31 ]) print(docID) // "[ "userId": "456abc", "workId": 789 ]"} catch { //handle error print(error)}
Note: _id
s with the same key and values will be equal regardless of their defined order. Thus, {a: "foo", b: 1} == { b: 1, a: "foo" }
. This is because Ditto maps check for equality of key and value combinations and do not consider for literal order.