17 Document Operations

Oracle Backend for Firebase provides a unified document-centric interface for interacting with both relational and document-based data. This section introduces the conceptual foundation for document operations, focusing on how developers can model, write, and read data using Oracle Backend for Firebase.

Document operations in Oracle Backend for Firebase refer to the lifecycle actions developers perform on JSON-based documents stored within collections. These operations include creating, updating, reading, and deleting documents, along with applying field-level modifiers and managing metadata. Oracle Backend for Firebase supports both document and relational models, and these operations apply primarily to the document model.

Information in this section is intended to help developers understand the underlying principles before diving into SDK-specific implementations.

17.1 Prerequisites

Before performing any document read or write operations, ensure the following:

  • Project Initialization: The Oracle Backend for Firebase project must be created and configured using the Console.

  • Authentication Setup: The application must be initialized using initializeApp() or equivalent. A valid Auth token must be included in all requests.

  • Database Configuration:

    • For collection model: The collection must be created and indexed if filters are used.

    • For relational model: The relational table must be mapped and duality views configured.

  • Security Rules: Appropriate rules must be published for the target path to allow get, list, create, update, or delete operations.

  • SDK Installation: The relevant SDK (JS, Android, iOS) must be installed and configured with the correct config.json.

  • Permissions:

    • Write operations require create, update, or delete access.

    • Read operations require get or list access.

  • Indexing:

    • Check if a functional index is required

    • Compound queries or ordering require indexes to be defined in the Console UI.

  • Collection Path: Identify the correct collection path where the document will be added.

17.2 Write Operations

Write operations in Oracle Backend for Firebase allow developers to create, update, and delete documents within collections. These operations are designed to support both full document replacements and granular field-level updates.

17.2.1 Supported Document Operations

Developers can perform the following operations on documents. Each of these operations can be invoked using REST or SDK interfaces.

Table 17-1 Write Operations

Operation Method Description

Set a Document

setDoc(path, data, options)

Create or overwrite a document at the specified path; can also merge document data. If the collection does not exist, it is created automatically.

Add a Document

addDoc(path, data)

Inserts a new JSON document into a specified collection or sub-collection with an auto-generated unique identifier (OID).

Update Document

updateDoc()

Updates specific fields in an existing document using its OID.

Delete Document

deleteDoc()

Removes a document from the collection.

Note:

For multi-step writes, use batch writes (all-or-nothing) or transactions (read + write atomically).

SDK Usage

  • JavaScript (Modular)
  • JavaScript (Namespace)
  • Flutter (Dart)
  • Java (Android)
  • Swift (iOS)
17.2.1.1 Set a Document

The setDoc() operation is used to create or overwrite a document at a specified path. Unlike addDoc(), which generates an auto-ID, setDoc() requires you to specify the document path within a collection and provide the document data.

If the document being created already exists, it can be overwritten entirely or updated partially using one of these merge options:

  • Overwrite Document (merge = false): Overwrite to replace the entire document with the provided data, which implies that all fields are replaced. This option should be used if you want to replace the complete document or when you are not sure if the document exists.
  • Merge Document (merge = true): Updates only the specified fields, preserving exisitng data of the document.

If the document does not exist, it will be created at the given path. If the collection does not already exist, this operation implicitly creates the collection. The field methods listed in Field-Level Semantics and Data Types can be applied. Relational Model updates operate on duality views created from relational tables.

Merging allows developers to update specific fields within a document without replacing the entire content. This is useful for incremental updates, such as modifying a title or adding new tags.

By default, when you call setDoc() without specifying merge options, the entire document is overwritten with the new data you provide.

Setting a Document Using the Console

  1. Navigate to the Database section in the Console.

  2. Select the Collection where you want the document.

  3. Choose Add Document but manually specify the document ID (For example, Scott, Cookies).

    Note:

    When you set a document you control the document ID. The Console requires you to type it in.

  4. Enter field values in the document editor.

  5. Optionally, enable merge mode (if supported in the Console UI) to update only specific fields.

  6. Save, and the document is created or overwritten at that exact path.

17.2.1.1.1 Example: Set a Document with Merge Options

Merge and MergeFields options are supported in Oracle Backend for Firebase to allow fine-grained control over document updates.

Overwrite Document (merge = false)

Setting a document with merge = false (which is the default) replaces the entire document with the provided data. Use this when you want to ensure the document is fully reset or when you are not sure if it exists.

{
  "displayName": "Scott",
  "photoURL": null
}

Merge Document (merge = true)

This option tells the system to merge the incoming fields with the existing document rather than replacing the entire document. Therefore, this operation adds new fields or updates specified existing fields. Other fields remain untouched. This option is useful for incremental updates without overwriting the entire document.

The following is an example input:

{
  "title": "Rich Chocolate Chip Cookies",
  "ingredients": "2 cups flour,1 cup sugar,2 cup chocolate chips"
}

The following is the resulting document, after it is merged into the existing document:

{
  "uuid": "Scott",
  "title": "Rich Chocolate Chip Cookies",
  "ingredients": "2 cups flour,1 cup sugar,2 cup chocolate chips",
  "avgRating": 0,
  "tags": ["sweet", "baking"]
}

Example 17-1 merge: true

The following updates only views and notes fields, leaving other fields untouched.

{
  "title": "Chocolate Chip Cookies",
  "ingredients": "2 cups flour,1 cup sugar,2 cups chocolate chips",
  "tags": { "arrayUnion": ["dessert"] },
  "createdAt": "serverTimestamp",
  "updatedAt": "serverTimestamp",
  "views": { "increment": 1 },
  "notes": "deleteField"
}

The following is the resulting document:

{
  "title": "Chocolate Chip Cookies",
  "ingredients": "2 cups flour,1 cup sugar,2 cups chocolate chips",
  "tags": ["sweet", "baking", "dessert"],
  "createdAt": "2025-12-22T12:53:00Z",
  "updatedAt": "2025-12-22T12:53:00Z",
  "views": 101,   // incremented from 100
  // "notes" field removed
}

mergeFields: ["field1", "field2"]

This option is more selective because it allows you to merge only specific fields from the payload, ignoring others even if they are present. This is different from a full merge (merge = true), which merges all provided fields. With merge fields, you can explicitly list which fields should be merged.

  • Only the fields listed in mergeFields are updated.

  • Other fields in the data payload are ignored.

  • Useful for partial updates when you want to avoid accidental overwrites.

Example 17-2 mergeFields: ["field1", "field2"]

Only field1 and field2 are updated. field3 is ignored even though it is present in the payload.

Suppose that the target document path is /users/Scott/recipes/Cookies and the content to be updated is:

{
  "title": "Rich Chocolate Chip Cookies",
  "ingredients": "2 cups flour,1 cup sugar,2 cup chocolate chips",
  "avgRating": 5
}

Suppose that the following merge fields option are used:

{
  "mergeFields": ["title", "ingredients"]
}

After applying the merge with mergeFields, the resulting document is as follows:

{
  "uuid": "Scott",
  "title": "Rich Chocolate Chip Cookies",
  "ingredients": "2 cups flour,1 cup sugar,2 cup chocolate chips",
  "avgRating": 0,              // unchanged because not listed in mergeFields
  "tags": ["sweet", "baking"]  // untouched
}
17.2.1.2 Add a Document

This operation adds a new document to a collection or a relational model with an auto-generated identifier. It is typically used when the document ID is not predetermined and allows for rapid creation of new entries. This operation is distinct from setDoc() (which overwrites or merges existing documents) because addDoc() always generates a new document with a system‑assigned identifier.

The add data operation is supported in both collection model (JSON) and relational model (duality view). When invoked:

  • A new document is created inside the specified collection.

  • If the collection does not exist, Oracle Backend for Firebase automatically creates it.

  • In relational setups, a hybrid collection is created as an extension to the relational table.

The modifier serverTimestamp stores the current server time, which is useful for createdAt fields.

Adding Data Using the Console

Developers can add data directly through the Console without writing SDK code.

  1. Navigate to the Database section of your project.

  2. Select the mapped relational table or document collection.

    For relational tables, ensure relational tables are mapped in the Console. Oracle Backend for Firebase automatically creates duality views for each mapping.

    For document collection, select the target collection path: users/{userid}/recipes/{recipeId}/notes.

  3. Click Add Document.

  4. Enter the JSON structure above into the document editor.

  5. Save the document.

    • The system generates a unique ID for the new note.

    • Metadata (OID, parent_oid, _metadata) is automatically generated.

    • The createdAt field is automatically populated with the server time.

Example: Adding Data in Document Model

When adding a new document into a subcollection (for example, notes under a recipe), the structure of the data can be represented as follows:

{
  "uuid": "Scott",
  "content": {
    "step1": "Try adding a pinch of sea salt for balance.",
    "step2": "Add extra chocolate chips"
  },
  "createdAt": "serverTimestamp"
}
  • uuid: Identifies the owner of the document (in this case "Scott").

  • content: Nested object containing the note details. Each step is stored as a key‑value pair.

  • createdAt: Uses the serverTimestamp attribute to automatically store the current server time when the document is created.

Adding Data in Relational Model

When using Oracle Backend for Firebase with relational tables, adding data creates a hybrid collection that extends the relational schema. Each relational table is converted into a duality view with metadata fields such as oid and parent_oid.

A new document added to such a hybrid collection can be represented in JSON as follows:

{
  "osons": {
    "name": "Scott",
    "age": 30,
    "about": "Application developer working with Oracle Backend for Firebase",
    "OID": "FB03C10200",
    "_id": 1,
    "parent_oid": "_docId",
    "_metadata": {
      "etag": "943EEC508908213D2D00FF375854BB48",
      "asof": "00000000000001234"
    }
  }
}
  • name / age / about: Standard relational fields mapped into the hybrid collection.

  • OID: Unique identifier for the document within the duality view.

  • _id: Internal system‑generated ID.

  • parent_oid: Reference to the parent document in the hierarchy.

  • _metadata: Contains system metadata such as etag (for versioning) and asof (snapshot reference).

17.2.1.3 Update a Document

Updating a document allows you to change only specific fields in an existing document. Unlike setDoc(), which overwrites or merges entire documents, the update operation is designed for partial modifications.

If the document does not already exist, the update operation fails. This ensures that updates are only applied to valid, existing records. Also, the update operation supports bulk updates using the filter clause, which iterate through each document that is part of the clause and updates the documents. In case of security issue with any of the document, the complete operation is rolled back.

When updating, the field methods listed in Field-Level Semantics and Data Types can be applied. Relational Model updates operate on duality views created from relational tables.

Updating a Document Using the Console

  1. Navigate to the Database section in the Console.

  2. Select the collection or relational duality view where you want to update the document.

    Example path: /users/{userid}/recipes/{recipeid}/notes/{noteid}

  3. Click the document ID to open its details.

  4. Enter field values in the document editor.

  5. Complete the following tasks:

    • In the document editor, specify the fields to be updated.

    • Use dot notation for nested fields (for example, content.step2).

    • Example update content:

      {
        "content.step2": "Add a handful of chopped nuts instead of chocolate chips",
        "content.step3": "Add some coffee as well"
      }
      
  6. Choose Update Document from the available actions and confirm the operation.

Example: Updating data in Document Model

In the earlier example for adding data, suppose you want to:

  • Modify step2 to suggest adding nuts instead of extra chocolate chips.

  • Add a new step3 with an additional instruction.

The update request would look like this:

{
  "content.step2": "Add a handful of chopped nuts instead of chocolate chips",
  "content.step3": "Add some coffee as well"
}

After the update, the document will contain:

{
  "uuid": "Scott",
  "content": {
    "step1": "Try adding a pinch of sea salt for balance.",
    "step2": "Add a handful of chopped nuts instead of chocolate chips",
    "step3": "Add some coffee as well"
  },
  "createdAt": "serverTimestamp"
}

Example: Updating Data in Relational Model

In the earlier example for adding data, suppose you want to:

  • Change the age field from 30 to 31.

  • Update the about field with new information.

The update request would look like:

{
  "age": 31,
  "about": "Updated profile information"
}

After the update, the duality view reflects the following:

{
  "osons": {
    "name": "Scott",
    "age": 31,
    "about": "Updated profile information",
    "OID": "FB03C10200",
    "_id": 1,
    "parent_oid": "_docId",
    "_metadata": {
      "etag": "NEW_ETAG_VALUE",
      "asof": "NEW_ASOF_VALUE"
    }
  }
}

Metadata (etag, asof) is automatically updated to reflect the new version.

17.2.1.4 Delete a Document

The delete operation removes an entire document from a collection or relational duality view.

  • When a document is deleted, all of its fields are removed.

  • Important: Subcollections are not automatically deleted. They remain in the database unless explicitly removed.

Caution:

This operation is irreversible and should be used with caution, especially in production environments.

Deleting Data Using the Console

  1. Navigate to the Database section of your project.

  2. Use the project hierarchy to browse to the correct collection or relational duality view.

    For document collection, select the target collection path: /users/{userid}/recipes/{recipeid}/notes/{noteid}.

  3. Search or filter to find the document you want to delete and click the document ID to open its details.

  4. Click Delete Document.

  5. Confirm the deletion when prompted.

Example: Deleting a Document

Suppose that the target document path: /users/Scott/recipes/Cookies/notes/note1 and the delete request is:

{
  "operation": "deleteDoc",
  "path": "/users/Scott/recipes/Cookies/notes/note1"
}

The document note1 is removed from the notes subcollection. Any subcollections under note1 (For example, attachments, comments) remain unless explicitly deleted.

17.2.2 Field-Level Semantics and Data Types

Oracle Backend for Firebase supports advanced field-level operations using built-in field modifiers that enhance document write operations. These modifiers are applied to manage dynamic data during document creation or update (set and update operations):

  • serverTimestamp: Stores the current server time (not client time), typically used for createdAt and updatedAt fields.

  • increment: Atomically increases or decreases (if in negative) a numeric field.

  • arrayUnion (values): Adds values to an array only if they do not already exist.

  • arrayRemove (values): Removes specified matching values or elements from an array.

  • deleteField: Deletes a field from a document.

These operations allow developers to perform complex updates without needing to read and rewrite entire documents.

serverTimestamp

  • Stores the current server time in the field.

  • Useful for tracking creation and update times consistently across distributed clients.

The following is an example of an input:

{
  "createdAt": "serverTimestamp",
  "updatedAt": "serverTimestamp"
}

The following is the example of the resulting document:

{
  "createdAt": "2025-12-22T15:37:00Z",
  "updatedAt": "2025-12-22T15:37:00Z"
}

increment

  • Atomically increases or decreases a numeric field.

  • Prevents race conditions when multiple clients update counters simultaneously.

The following is an example of an input:

{
  "views": { "increment": 1 }
}

The following is the example of the resulting document (if previous value was 100):

{
  "views": 101
}

arrayUnion

  • Adds one or more values to an array field.

  • Ensures values are only added if they don’t already exist.

The following is an example of an input:

{
  "tags": { "arrayUnion": ["dessert"] }
}

The following is the example of the resulting document (if previous tags were ["sweet", "baking"]):

{
  "tags": ["sweet", "baking", "dessert"]
}

arrayRemove

  • Removes one or more values from an array field.

  • If the values don’t exist, the operation has no effect.

The following is an example of an input:

{
  "tags": { "arrayRemove": ["baking"] }
}

The following is the example of the resulting document (if previous tags were ["sweet", "baking", "dessert"]):

{
  "tags": ["sweet", "dessert"]
}

deleteField

  • Deletes a field from the document.

  • The field is removed entirely, not just set to null.

The following is an example of an input:

{
  "notes": "deleteField"
}

The following is the example of the resulting document:

{
  // "notes" field removed
}

Combined Example

Developers can combine multiple field methods in a single operation:

The following is an example of an input:

{
  "title": "Chocolate Chip Cookies",
  "ingredients": "2 cups flour,1 cup sugar,2 cups chocolate chips",
  "tags": { "arrayUnion": ["dessert"] },
  "createdAt": "serverTimestamp",
  "updatedAt": "serverTimestamp",
  "views": { "increment": 1 },
  "notes": "deleteField"
}

The following is the example of the resulting document:

{
  "title": "Chocolate Chip Cookies",
  "ingredients": "2 cups flour,1 cup sugar,2 cups chocolate chips",
  "tags": ["sweet", "baking", "dessert"],
  "createdAt": "2025-12-22T15:37:00Z",
  "updatedAt": "2025-12-22T15:37:00Z",
  "views": 101
  // "notes" field removed
}

Supported Data Types

The allowed data types for write operations include:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date

17.2.3 Security Rule Enforcement

Before running any document operation, Oracle Backend for Firebase system validates the request against CEL-based security rules for database documents. These rules are compiled into SQL expressions and enforced at runtime to determine whether a user is authorized to perform a given operation on a document or collection.

The following must be noted about security rule enforcement:

  • Rules are enforced at the document level, not just collection level.

  • Multiple rules can be defined per collection, scoped by operation.

  • Rules are stored and managed centrally through baas_securityrule_metadata.

Each rule entry includes:

Field Description

collection_name

Target collection or sub-collection

operation

Type of operation (For example, addDoc, updateDoc)

rule_expr

CEL expression that defines access logic

enabled

Boolean flag to activate or deactivate the rule

Supported Operations

Rules can be defined for the following operations:

  • addDoc

  • updateDoc

  • deleteDoc

  • setDoc

  • getDocs

  • listDocs

Each rule is evaluated before the operation is executed. If the rule fails, the operation is blocked and an error is returned.

Example 17-3 Rule

To restrict updates to documents where the user is the creator:

rule_expr = "request.auth.uid == resource.data.created_by"

This ensures that only the original creator can update the document.

Variables for CEL rules

Variable Description

request.auth

Authenticated user info (For example, uid, email)

request.time

Timestamp of the request)

resource.data

Existing document data

request.data

Incoming payload data

17.3 Read Operations

Read operations in Oracle Backend for Firebase allow developers to retrieve structured data in documents from both collection-based and relational models. These operations are designed to be shallow by default, meaning that subcollections are not automatically fetched unless explicitly requested.

Read operations have the following characteristics:

  • Read data is a select query on defined table. By default ORDS infrastructure fetches data in batches.
  • Number of rows will be decided based on document size.
  • Use limit clause along with pagination to query data based on application requirement.
  • Read can be used along with where, limit, startAt, and so on, each helping filter the result set.
  • The fetch document operation with each read call always returns complete document data (no partial read).

Oracle Backend for Firebase supports two primary models for document storage and retrieval. Each model supports full document retrieval, filtered queries, and advanced operations like joins and collection groups.

  • Collection Model: JSON-style documents organized in collections and subcollections.

  • Relational Model: Documents derived from relational tables using duality views and mappings.

Example 17-4 Collection Model Read Output

{
  "ret": [{
    "osons": {
      "DOCUMENT": {
        "displayName": "User123",
        "email": "user123@example.com"
      },
      "OID": "ABCDEF123456",
      "CREATED": "2023-10-25T14:00:00Z",
      "LAST_MODIFIED": "2023-10-25T14:00:00Z",
      "VERSION": 1
    }
  }]
}

Example 17-5 Relational Model Read Output

{
  "ret": [{
    "osons": {
      "name": "Scott",
      "age": 1142568,
      "about": "Some data",
      "OID": "FB03C10200",
      "_id": 1,
      "parent_oid": "_docId",
      "_metadata": {
        "etag": "943EEC508908213D2D00FF375854BB48",
        "asof": "00000000000001234"
      }
    }
  }]
}

17.3.1 Supported Read Operations

You can perform the following read operations on documents:

Table 17-2 Read Operations

Operation Method Description

Read a Specific Document

getDoc()

Retrieves a specific document using its OID. Supports both document and relational models.

List Documents

getDocs()

Fetches all documents in a collection, optionally filtered by conditions.

Read a Specific Document

This operation retrieves a single document using its unique identifier within a collection.

The conceptual flow is:

  1. Specify the collection and document ID.

  2. Execute a getDoc operation.

  3. Validate existence and extract data.

Read All Documents in a Collection

This operation retrieves all documents within a specified collection path. This is useful for listing entities like users, recipes, or posts.

The conceptual flow is:

  1. Specify the collection path.

  2. Execute a getDocs operation.

  3. Iterate over the returned documents.

17.3.2 Query Capabilities and Semantics

Oracle Backend for Firebase supports a wide range of query filters and modifiers:

Filters

These filters can be applied to fields within documents to retrieve matching results:

  • Equality (==), Inequality (!=), and Greater/Less than (>, >=, <, and <=)

  • Array Membership: array-contains, array-contains-any

  • Set Membership: in, not-in

Modifiers

These modifiers allow developers to fine-tune their queries for performance and relevance:

  • Select: Retrieve only specific fields from a document.

  • orderBy(field, direction): Sort results based on field values.

  • limit(n): Restrict the number of results returned.

  • startAt()/endAt(): Paginate by values

  • startAfter()/endAfter(): Paginate by document

  • Collection Group: Query across all collections with the same name.

  • Join: Perform joins across collections or relational views.

Query Semantics

Queries are executed against collections or collection groups. Results are returned as shallow documents, meaning that nested subcollections must be queried separately. This design promotes modular data access and avoids unnecessary data transfer.

In a relational context, Oracle Backend for Firebase uses metadata tables to determine primary and foreign key relationships. This information is used to construct join queries that simulate hierarchical document access. In a document context, queries operate directly on JSON documents and support flexible filtering and sorting.

17.3.2.1 Filtering with Conditions

Oracle Backend for Firebase supports expressive filtering using conditional operators. These filters can be applied to fields within documents to narrow down results. The conditions array enables developers to filter documents based on field values.

Table 17-3 Supported Operators

Operator Description Example Use Case

==

Equal to

Find recipes where category == "Dessert"

!=

Not equal to

Exclude recipes where category != "Dessert"

> / < / >= / <=

Numeric comparisons (Greater than / Less than / Greater than or equal to / Less than or equal to?

Filter by views > 1000

array-contains

Match array element

Tags include "sweet"

array-contains-any

Match any array element

Tags include "sweet" or "baking"

in

Match any field value in array

Category is "Dessert" or "Snack"

not-in

Exclude Values: Field value not in array

Category is not "Dessert" or "Snack"

Example 17-6

"conditions": [
  { "field": "upd_by", "op": ">=", "value": "01/01/2023" },
  { "field": "upd_by", "op": "<=", "value": "11/01/2023" },
  { "field": "verified", "op": "==", "value": true }
]
17.3.2.2 Ordering and Pagination

To manage large datasets, Oracle Backend for Firebase supports ordering and pagination modifiers:

Table 17-4 Ordering and Pagination Modifiers

Modifier Description

orderBy(field, direction)

Sort results by a field (asc or desc)

limit(n)

Restrict result count

Use the limit field to control how many documents are returned. A value set as "limit": 0 means no limit is set. Setting limit can be useful for paginated user interfaces or infinite scroll implementations.

startAt(value) / endAt(value)

Paginate by value range

startAfter(doc) / endBefore(doc)

Paginate by document reference

array-contains-any

Match any array element

in

Match any field value in array

not-in

Exclude Values: Field value not in array

Example Use Cases

Retrieve recipes created in 2025, ordered by creation date:

  • orderBy("createdAt")

  • startAt("2025-01-01")

  • endAt("2025-12-31")

  • "limit": 10

Ordering using explicitOrder

The explicitOrder array allows sorting results by one or more fields.

"explicitOrder": [
  { "field": "upd_by", "direction": "asc" },
  { "field": "priority", "direction": "desc" }
]

direction can be "asc" or "desc".

17.3.2.3 Collection Group and Join Queries

Collection Group Queries

A collection group allows querying across all subcollections with the same name, regardless of their parent document hierarchy. For example, Query all notes subcollections under different recipes.

The following prerequisites for using collection group queries:

  • Index must be created for the group.

  • Security rules must be defined for the group path.

Join Queries

Join queries allow developers to combine data from multiple collections or relational duality views into a single result set. This is useful when related information is stored across different collections and needs to be queried together.

The following setup must be completed before using Join Queries:

  • Define joins in the Console.

  • Ensure each table is part of the relational setup.

  • Publish security rules for the join path.

    match /EMP_DEP/_docId {
      allow get: if request.auth != null;
    }
    

For relation joins, currently, only INNER JOINs are supported. All joined tables must share a common key (using).

In the following example, joins are applied in the order listed. Joins are not treated as actual collections (no docRef is returned for joined rows).

The following is the general workflow:

  • Identify the collections or views you want to join.

  • Specify join conditions (For example, matching fields across collections).

  • Execute the query with conditions, ordering, and limits.

  • Review the combined result set returned by the system.

Example 17-7 Join Query

Suppose that the target collections are Cities collection and Employees collection, the join query request is as follows:

{
  "path": ["Cities"],
  "conditions": [
    { "field": "COUNTRY", "op": "=", "value": "USA" }
  ],
  "limit": "2",
  "joins": [
    {
      "collection": "Employees",
      "on": { "field": "CITY_ID", "op": "=", "value": "Cities.ID" }
    }
  ],
  "explicitOrder": [
    { "field": "POPULATION", "direction": "asc" }
  ],
  "aggregate": []
}

The resulting output is as follows:

{
  "ret": [
    {
      "osons": {
        "DOCUMENT": {
          "NAME": "NewYork",
          "COUNTRY": "USA",
          "POPULATION": 123455678,
          "EMPLOYEE": {
            "EmployeeID": "2",
            "FirstName": "John",
            "LastName": "Morrow",
            "Email": "Marston17@norton.net"
          }
        },
        "CREATED": "2025-01-24T08:03:27.014334",
        "LAST_MODIFIED": "2025-01-24T08:03:27.014334",
        "VERSION": 1,
        "OID": "2C6F2A7F590D231BE0631F965E6400A4"
      }
    }
  ]
}
  • joins define which collections are combined and the condition for joining.

  • explicitOrder allows sorting results after the join.

  • aggregate can be used for grouped calculations (For example, avg, sum).

  • Joins are supported across both document collections and relational duality views.

  • Security rules must allow access to all collections involved in the join.

17.3.2.4 Aggregation Functions

The aggregate array allows applying SQL-style aggregation functions on fields.

The supported functions are:

  • sum

  • avg

  • count

"aggregate": [
  { "field": "age", "func": "sum", "op_key": "sumofage" },
  { "field": "score", "func": "avg", "op_key": "avgscore" }
]

op_key is the alias used in the result for each aggregation.