---
title: CRUD Operations
slug: v4-4/V5eBeM0ww-xU1B4tE8Czc
docTags: 
createdAt: 2023-08-18T16:00:44.419Z
---

Ditto's query engine and API methods allow you to perform traditional create, read, update, and delete (CRUD) operations.&#x20;

This article provides an [introduction](./#introduction) to querying operations in Ditto and the [fundamental concepts](./#fundamental-concepts) to know.&#x20;

:::hint{type="info"}
For comprehensive information, how-to instructions, as well as code examples in each language, see any of the following children articles:

- [Finding and Observing](docId\:HvfMp8TX4CwKI4h2xoTuy)
- [Upserting and Updating](docId\:L2hFjvzUYyNu5ahZXHwAJ)
- [Evicting and Removing](docId\:Q6vsBHCzgyPt1HlZgOW4E)
- [Best Practices for CRUD](docId\:C-V5Q9JYhmVeMVSDIpj2U)
:::

:::hint{type="info"}
If you're using Ditto's Big Peer cloud deployment, for an overview of the HTTP API for data egress, as well as the LiveQuery Webhook for real-time bidirectional change data capture (CDC) with a third-party data product, see the *Platform Manual&#x20;*> [Big Peer](docId\:h-CbSPSTNhl5VEceERB0M).
:::

# Introduction

In Ditto, you use queries to read data from local Ditto stores, and various methods to perform CRUD operations.

When interacting with the platform, you'll notice that Ditto's query language is quite similar to what you'd expect in most `if` statements.&#x20;

You'll use familiar techniques like using an `update` statement to modify existing data, `dot` notation to navigate levels in a hierarchy, upon other intuitive query condition operators typical for performing standard CRUD.&#x20;

:::hint{type="info"}
For a complete overview of the syntax you can use in your queries, see [Query Syntax](docId\:MMTiSmYkR3HxZmYS1bi2w).
:::

The Ditto SDK provides a comprehensive set of methods and functions to facilitate data interaction and perform a wide range of operations in your app:

- For read operations, use the Find and Observe Local methods.

- For write operations, use the Update, Upsert, Evict, and Delete methods.

# Fundamental Concepts

At a high-level, queries operate on collections rather than individual documents. This approach to data management enhances retrieval efficiency and ensures seamless data replication among connected peers.

For an overview of the syntax you can use to filter your queries, see *Ditto Basics&#x20;*> [Syntax](docId\:bYukQ4ekkuevjbx_FEuOg) .

The following table provides an overview of the three types of queries you use to fetch documents and set up listeners in your app:

| **Type**          | **Description**                                                                                                                                                                                                                                                                                                                            | **Use Case**                                                                                                                                                                            |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Local query       | - Invoked by way of either the `find` or Find By ID method.
- The *local query* specifies your operation to execute as a single operation on its local datastore.                                                                                                                                                                          | You want to quickly search or retrieve specific data, such as an `attachment`, recent activities, and so on, that is stored within a particular local Ditto store.                      |
| Live query        | * Established through the  Observe Local method.
* You use the *observe query* to define your observe criteria.&#x20;
* Once your observe conditions are met, Ditto automatically triggers an  `observe` callback function that executes the subsequent actions based on your observe query in your app.                                   | You want to display realtime updates to your end user any time you receive an incoming remote change sent from another connected peer.                                                  |
| Replication query | - Activated using the `subscribe `method, which sets up your subscription.
- The *subscription query* instructs specify your query conditions.&#x20;<br />When these conditions are observed within the mesh, Ditto automatically triggers a `subscribe` callback object that executes your subsequent processes and actions in your app.  | You want to receive notification whenever changes are made by any peer participating in the mesh, so you can respond as appropriate to ensure realtime collaboration with remote peers. |

## Finding and Observing

There are two methods you can use to retrieve documents stored at your local Ditto store:

- `find`—  Returns all local documents that match your criteria.
- `findById`— Returns only the local document assigned the `_id` you provide.

If you're interested in actively listening for changes and events in the data so you can react accordingly, convert the local query to a live query by adding the `observeLocal` method in the enclosure.&#x20;

When working with data subject to change at runtime, instead of building or interpolating query `strings`, you can query with runtime variables through an `$args` `map` object.&#x20;

For more information and how-to instructions, see [Finding and Observing](docId\:HvfMp8TX4CwKI4h2xoTuy).

## Subscribing

Unlike the Observe Local method, which establishes a local listener, the `subscribe` method establishes a mesh-wide listener so you can stay up-to-date with data changes happening across remote peers.

Once you've initiated data replication by invoking the Start Sync method, you can set up a subscription to signal which data you're interested in automatically receiving updates for, as well as the subsequent actions for Ditto to perform in your app.&#x20;

Given this subscription-driven approach, you eliminate the need to perform traditional resource‑intensive and time‑consuming methods of data retrieval in your app, such as repeatedly executing HTTP requests and polling a queue for data updates.

For more information and how-to instructions, see [Finding and Observing](docId\:HvfMp8TX4CwKI4h2xoTuy).

## Updating and Upserting

There are two ways you can write changes to Ditto: `upsert` the changes or `update` the changes.&#x20;

Choosing which to use depends on what you're trying to achieve:

- With the Update method:
  - You can query a property locally, and then make changes to each individual property only if that property has changed.&#x20;

  - You can create fine-grained changes to a single document or make batch changes to a set of documents.&#x20;

- Due to Ditto’s conflict-free eventual consistency data model, there is no concept of “insert”; instead, each device assumes that their write transaction already exists somewhere in the broader Ditto system.&#x20;

  Therefore, with the Upsert method:

  - You can `upsert` only the fields within the document that have changed.&#x20;

  - If all of the fields in the document are new, Ditto creates an entirely new document object and, unless manually supplied, generates and assigns that document a unique identifier, the `_id`.

:::hint{type="info"}
For more comprehensive information, see For more information, see [Upserting and Updating](docId\:L2hFjvzUYyNu5ahZXHwAJ).
:::

## Evicting and Removing

There are two approaches to removing data in Ditto, and the decision of which to choose depends on your specific requirements and use case:

:::hint{type="danger"}
Invoking the Remove method results in irreversible data loss. &#x20;
:::

- Remove — Permanently deletes one or more specified documents from a collection throughout the entire Ditto platform.&#x20;

- Evict —  Physically eliminates the specified documents from its Ditto store to free up local memory or on-disk storage, prevents any pending changes affected by the eviction from being sent across the mesh network, and leaves the documents stored in remote Ditto stores intact so they remain accessible to all connected peers.&#x20;

- Soft-delete pattern  — Adds a "forget" flag to the specified documents indicating that, although still accessible to remote peers for inspection and viewing, write operations, are restricted.

For more information and how-to instructions, see [Evicting and Removing](docId\:Q6vsBHCzgyPt1HlZgOW4E).

## Establishing Relationships

You can model relationships between your data using [foreign‑key relationships](docId:1CEXFnSWhjeqa_R6yyL-8) and [key‑value pair relationships](docId:1CEXFnSWhjeqa_R6yyL-8) by way of embedded `maps` and `arrays`.&#x20;

:::hint{type="info"}
Ditto does *not* support nesting documents within documents. If you need to create relationships between documents, use a foreign-key relationship by referencing the document ID. For more information, see [Foreign-Key Relationship](docId:1CEXFnSWhjeqa_R6yyL-8).
:::

For more information, see any of the following:

- For an overview of Ditto's advanced types, see [Data Types](docId\:yxemKH1COm3CSUuMqcnlf).
- For more information about relationships, see [Relationships](docId\:LQGzvVHtqzybx_ALD5b8J).

