website logo
Legacy DocsPortal
⌘K
Welcome to Ditto
Onboarding
Ditto Basics
SDK Setup Guides
Platform Manual
HTTP API
Kafka Connector
Use Cases
FAQs
Troubleshooting Guide
Support
Docs powered by
Archbee
Platform Manual

Document Model

18min

As a datastore that leverages conflict-free replicated data type (CRDT) technology to enable advanced sync capabilities, the foundation of each document is represented as a CRDT map. That is, when you invoke the Upsert API and create a new document object, you form a top-level map object at its root.

For example, the following snippet of a basic JSON-like document object actually represents a single map object:

Text
|
{
  "_id" "123abc",
  "name": "Sam",
  "age": 45,
  "isOnline": false
}


If you need to represent a highly-complex dataset in a document, you can embed a map within another map. For more information, see Embedding Map Structures, as follows.

Embedding Map Structures

Embedding a map provides a way for you to structure and organize related data within a single document to create a complex structure with multiple levels of hierarchy. As in, you can embed a map within a map, within another map, within another map, and so on.

For example, the following snippet shows three levels of embedded maps: details, engine, interior, and features.

Text
|
{
  "_id": "123abc",
  "make": "Toyota",
  "model": "Corolla",
  "year": 2022,
  "details": {
    "engine": {
      "type": "Gasoline",
      "displacement": "1.8L"
    },
    "interior": {
      "seats": 5,
      "color": "Black"
    },
    "features": {
      "safety": {
        "airbags": 6,
        "antilockBrakes": true
      },
      "technology": {
        "infotainment": "Touchscreen",
        "navigation": true
      }
    }
  }
}



Each level contains its own key-value pairs and, if used, children-level maps. You can represent key values using a register, counter, array, or another map. For more information, see Data Types.

Avoid using arrays in Ditto.

Due to potential merge conflicts when offline peers reconnect to the mesh and attempt to sync their updates, especially when multiple peers make concurrent updates to the same item within the array.



Benefits of Embedding Maps

Embedding maps is beneficial in scenarios where you need to manage a collection of items and continuously modify that collection over time; that is you want to link multiple data items with a single unique string identifier, but you anticipate that these data items are subject to concurrent edits over time.

As an example, the following snippet demonstrates a basic Point-of-Sale (PoS) system where you need to keep track of the customer orders collection. And, since multiple users can add and remove orders within the collection, you embed a map to represent the ordered items, where each key denotes an item ID and the linked value indicates the quantity ordered:

pseudocode
|
const order = {
  customerName: 'John Doe',
  orderDate: '2023-08-15',
  items: {
    'item123': 2, // Item ID: Quantity ordered
    'item456': 5,
    'item789': 1
  }
};

// Inserting the order into the Ditto collection
await ditto.store.collection('orders').upsert(order);


Evaluation Criteria

The decision to use deeply embedded maps in a single document or instead distribute that data across multiple documents depends on your specific requirements, relationships between data, and tolerance for certain tradeoffs.

When assessing whether to embed maps in a document or distribute the data across multiple smaller documents, refer to the following criteria to guide you:

  • Data Complexity
  • Query Performance
  • Data Size
  • Concurrency Considerations
  • Document Structure
  • Future Scalability

Data Complexity

The following table provides a criteria for the levels of complexity in your data model:

Criteria

Type

You have a clear relationship between data items stored together in a collection.

map

Your data items are relatively simple and do not need a strong relationship.

Documents

Query Performance

The following table provides a criteria for speed and efficiency of read and write operations:

Criteria

Selection

You frequently retrieve or update the embedded map items together.

map

You frequently access or modify only certain parts of the data.

Documents

Data Size

The following table provides a criteria for potential size of the embedded map:

Syncing large documents can significantly impact network performance:

Caution is advised when handling large binary data, such as a high-resolution image or video exceeding 50 megapixels; a deeply-embedded document; or a very large document.

Instead of storing files exceeding 250kb directly within a document object, carefully consider using attachments . For more information, see Attachment Objects.

Criteria

Selection

You do not anticipate the embedded map to become too large and potentially impact overall system performance.

map

You anticipate the embedded map to increase in complexity and size and therefore become difficult to manage and so large that system performance degrades.

Documents

Concurrency Considerations

The following table provides a criteria for potential for concurrent edits and resulting merge conflicts:

Criteria

Selection

It is very likely that your end users will modify the same data items stored locally on their respective environments while internet is unavailable.

map

It is not likely that your end users will modify the same data items stored locally on their respective environments while internet is unavailable.

Documents

Document Structure

The following table provides a criteria for assessing the overall structure of your documents:

Criteria

Selection

Your embedded maps are relatively simple in structure and do not require maintainability over time.

map

Multiple embedded maps are becoming deeply nested; as in you have a embedded maps representing three or more levels in an hierarchy, necessitating for better organization.

Documents

Future Scalability

The following table provides a criteria for assessing how your data model may evolve over time:

Criteria

Selection

You anticipate that you'll add more data or expand relationships in the future.

map

You do not anticipate that you'll add more data or expand relationships in the future.

Documents

Adding or Updating a Map

Using the Upsert API, do the following:

1

Specify the document collection where you want to embed the map.

2

Identify the parent document field property (object) that will contain themap.

3

Define the key-value pairs that will form the map structure (object).

pseudocode
|
await ditto.store.collection('collection name').upsert({
  property: { key: 'value' },
});


The following snippet demonstrates embedding a map object with two key‑value pairs in all documents in the cars collection that have toyota as a field property:

pseudocode
|
await ditto.store.collection('cars').upsert({
  toyota: {
    engine: 'automatic',
    camera: false
  }
});










Updated 27 Sep 2023
Did this page help you?
PREVIOUS
Data Sync
NEXT
Fields and Map Key-Values
Docs powered by
Archbee
TABLE OF CONTENTS
Embedding Map Structures
Benefits of Embedding Maps
Evaluation Criteria
Data Complexity
Query Performance
Data Size
Concurrency Considerations
Document Structure
Future Scalability
Adding or Updating a Map
Docs powered by
Archbee