Finding and Observing
This topic provides an overview of essential methods for document retrieval, query formulation, and real-time monitoring.
Just like with conventional database querying, you execute query operations to fetch one or more documents that satisfy specific criteria and conditions, as well as to set up listeners for the data you're interested in watching.
Use the find and findById methods for executing single queries against the local Ditto store. Once invoked, these methods retrieve documents based on the query you provided as an argument:
Additionally, when working with dynamic changes, for ease, convenience, and flexibility, you can define and use values within a top-level args variable for your queries, as opposed to needing to separately adjust each individual query structure and conditions change.
For more information, see $args for Dynamic Data.
The Find API executes a single query against the Ditto store, targeting to retrieve one or more documents within a given collection based on a certain criteria.
You can search for documents within a collection against a wide range of criteria, from very broad conditions to more specific filters.
For instance, you can look for documents in a collection based on general conditions, such as "find all documents in the 'cars' collection with the field 'color' set to 'blue'."
Or narrow the focus of your search and use various filter options, including comparison operators (like greater than, less than), logical operators (AND, OR), upon many other tools Ditto offers for precisely adjust your filters. For an overview of the filter options you can use to create complex search criteria in your queries, see Ditto Basics > Query Syntax.
In your find function, indicate the document collection to query and define a condition that determines which documents to return.
For example, the following find function, when invoked, searches the cars collection for documents with the field color set to blue:
The Ditto query engine supports various filter operations for optimal data retrieval.
As the basis of data organization and access in Ditto, the query engine indexes the document _id so you can quickly and precisely access your data.
The first set of fields within each document uniquely identifies the data that its document object encodes. When grouped in a collection, this _id serves as the primary key identifying the document in the collection.
Each document must be assigned a unique identifier. When invoking the upsert method to create a new document, unless manually supplied, Ditto automatically generates and assigns the new document a 128‑bit Universally Unique Identifier (UUID).
For instructions on how to fetch a document by _id, see any of the following as appropriate:
- Default UUID: If you did not supply a custom document ID, see String ID Lookup for instructions on retrieving a document by its Ditto-generated and -assigned UUID.
- Custom string: If you provided a string value for the _id parameter when calling the Upsert API during document creation, see String ID Lookup.
- Custom JSON blob object: If you provided two or more embedded fields for the _id parameter when calling the Upsert API during document creation, see Composite ID Lookup.
Fetch a single document by its primary key: the document _idfield by invoking the Find By ID method.
The following snippet demonstrates a Find By ID operation that, once called, searches for the document assigned the 123456 unique identifier:
If supplying your own document ID, you can encode your value in a stringor, if forming a composite key, a JSON blob object made up of two or more values of the string or number type.
You can configure a custom document ID only at the time of document creation.
Once a document is created, to ensure consistency and uniqueness throughout the platform, the unique identifier that either Ditto automatically generated and assigned or you manually assigned becomes permanent and cannot be changed at a later time.
Handling dynamic-changing data introduces challenges that impact your end-user experience, as well as the maintainability, security, and performance of your app.
When invoking the find and observeLocal methods to query values that may change dynamically during runtime, you can declare a top-level args variable that defines the dynamic values, and then pass the the $args identifier within your query conditions. That way, the query engine separates your query logic from the data so you can easily define and pass values as needed to adapt without having to change the query structure itself.
Using strings to filter dynamic data may impact the maintainability, security, and performance of your app by introducing various issues such as syntax errors in your code.
For example, the following snippet illustrates a local query using the string "color == $args.color":
In addition to the using various operators and string formats to construct conditions in your queries, you can also control the results that are returned from calls to the find and findById functions:
Restrict the number of results returned by your query by using the limit method to specify the number of results you want to return.
The following snippet demonstrates a limit operation set for 100 query results:
Sort results by specific order by using the sort method to specify the field to match and the order want matching query results to be arranged.
By default, queries that do not include a sort operation, filter by document ID.
The following snippet demonstrates a sort operation on the miles field with results arranged by ascending order:
To enhance query efficiency, you can perform both sort and limit operations within a single query, as follows:
In scenarios where you want to continuously watch changes occurring to your local Ditto store in real‑time, use live queries. With a live query, you signal which changes you're interested in watching and define the callback function that Ditto triggers as a response.
You can create a live query object to store a single live query or a live query object that stores multiple live queries. For more information, see Creating a Collection of Live Queries.
To set up a single live query, as demonstrated in the following snippet:
- In the top-most scope of your app, declare a live query object.
- Specify the event you're interested in watching. For example, the cars collection where the color is black.
- Through the observeLocal method, define the subsequent callback function that you want Ditto to execute in your app.
For example, the following snippet demonstrates an observeLocal method that monitors changes in the cars collection where the color is "blue".
When the changes occur, the total number of documents display to the end user.
A live query callback has two arguments: collection and event. There are two types of events:
- Initial: The first event to return. (This event is returned only once.)
- Update: The event to return each time the results of your live query change. It contains information about the set of documents that previously matched the query before the update, along with information about what documents have been inserted, removed, updated, or moved (upserted), as part of the set of matching documents.
For more information, see LiveQueryEvent in the API References for your language.
To create multiple live queries stored in a single live query object that you can use to add live queries, remove specific ones, and stop all live queries at once, create a custom class that encapsulates your management logic, an array or a map:
For more information, see the API references.
To cancel a live query, call stop on the live query object you set up to establish your live query.