MongoDB to Oracle Migration with the Oracle Database API for MongoDB 

Executive Summary

Kovaion Consulting, an active Oracle Partner Network member, has successfully migrated Engage – its production low-code MERN-stack ERP platform used internally by the entire organisation – from native MongoDB onto the Oracle Database using the Oracle Database API for MongoDB, served through Oracle REST Data Services (ORDS).

This work was carried out under the Oracle Partner Enablement Plan for MongoDB Migrations, providing a real, end-to-end reference implementation of Oracle’s prescribed four-phase migration methodology. The migration preserved the existing MongoDB document model and application code path, while moving the underlying datastore to a converged Oracle Database – unlocking enterprise-grade reliability, JSON Duality, advanced security, and a single platform for relational, JSON, vector, graph, and spatial workloads.

This document describes the engagement, the technical implementation of ORDS and the Mongo API endpoint, the application-layer challenges encountered during cutover, and the practical solution Kovaion engineered using a SQL-based query layer. It is intended both as a delivery artefact for the Engage migration and as a repeatable playbook Kovaion can offer to clients undertaking similar MongoDB-to-Oracle modernisation programmes.

Engagement at a Glance

ItemDetail
PartnerKovaion Consulting (Oracle Partner Network member)
ProgrammeOracle Partner Enablement Plan – MongoDB Migration to Oracle
Workload migratedEngage – internal ERP / low-code platform (engage.kovaion.com)
Source stackMERN (MongoDB, Express, React, Node.js / Fastify)
Target stackOracle Database 23ai (PDB: KOVPDB) with ORDS 25.4 and Oracle Database API for MongoDB
Migration effortLow-effort path – no document re-modelling required at the database layer
ApproachOracle’s four-phase methodology: Plan → Prepare → Execute → Validate

About Kovaion and the Engage Platform

Kovaion Consulting

Kovaion is an Oracle Partner Network member specialising in Oracle Cloud Infrastructure, Oracle Database modernisation, enterprise application implementation, and low-code product engineering. Through its OPN membership and active NDA framework, Kovaion is positioned to deliver the standards-aligned, confidential migration projects called for under Oracle’s Partner Enablement Plan.

The Engage Platform

Engage (engage.kovaion.com) is Kovaion’s in-house low-code application platform, built on a MERN stack and used company-wide as the organisation’s ERP backbone. It hosts a broad portfolio of business modules – including RecruitHub for end-to-end talent acquisition, an internal Help Desk, HR workflows, internal job postings and mobility, project tracking, and approvals – all composed visually on the platform’s low-code framework.

The screenshot below shows Engage’s RecruitHub Recruitment Dashboard in production use, surfacing the live state of the talent-acquisition pipeline: profile screening, multi-stage interviews (L1, L2, HR), offer processing, and onboarding, alongside recruitment-status and applicant-by-month analytics. This is one of many modules Engage delivers from the same underlying low-code platform.

Figure 1 – Engage RecruitHub: live Recruitment Dashboard in production

Because Engage is the system of record for day-to-day operations across Kovaion, any change to its persistence layer carried two strict requirements: zero data loss and minimal disruption to the application code that hundreds of internal users rely on. Those requirements made Engage an ideal candidate for the low-effort migration path enabled by the Oracle Database API for MongoDB – and a credible, high-stakes proving ground for the methodology Kovaion now offers to its clients.

Why the Oracle Database API for MongoDB

The Oracle Database API for MongoDB exposes an Oracle Database as a Mongo-wire-protocol endpoint. Applications written against the MongoDB driver can connect to Oracle without changing connection idioms, document model, or – in most cases – application code. JSON documents are stored natively in the Oracle Database and remain queryable through the same MongoDB CRUD and aggregation operations the application already uses.

Why it was the right fit for Engage

  • Low-effort migration path. The existing JSON document model from MongoDB was preserved, eliminating the re-modelling cost that a relational rewrite would have imposed on a live ERP system.
  • Application compatibility. Engage’s Node.js / Fastify backend already used the standard MongoDB driver pointing it at the Oracle endpoint required configuration changes, not a rewrite.
  • Operational consolidation. Running Engage on Oracle places the platform on a single converged database alongside Kovaion’s other Oracle workloads – one backup, one HA strategy, one security model.
  • Forward path to innovation. Once the data is on Oracle, Engage can progressively adopt JSON Duality views, in-database analytics, and 23ai capabilities such as AI Vector Search without a second migration.

This aligns with Oracle’s three-stage value model – Migrate, Optimise, Innovate – where the first stage moves the workload with minimal friction, and subsequent stages unlock the converged-database advantages over time.

Migration Approach

The Engage migration followed Oracle’s prescribed four-phase methodology end-to-end. The phases below summarise how each was executed against Engage.

1. Planning

  • Complexity assessment of the existing MongoDB collections backing Engage, including authentication, OTP, and ERP transactional collections.
  • Stakeholder alignment with internal Engage users to capture availability windows, acceptable downtime, and data-integrity criteria.
  • Definition of clear migration goals: preserve the document model, preserve the application API surface, and validate business workflows post-cutover.

2. Preparation

  • Provisioning of the target Oracle environment – Oracle Database 23ai (PDB: KOVPDB) on the Kovaion estate, with ORDS 25.4 deployed at /u01/ORDS_HOME and configured against /u01/ords_config.
  • Compatibility checks against MongoDB aggregation operators used by Engage, with remediations identified up front (covered later in this document).
  • Schema and access design in Oracle, including a dedicated database user (STAGE1_ENGAGE) with the SODA_APP role and ORDS schema enablement.

3. Execution

  • Installation and configuration of ORDS in the target PDB.
  • Activation of the Mongo API endpoint on port 27017.
  • Connection of Engage’s Node.js backend to the new Oracle-backed Mongo endpoint.
  • Data transfer from MongoDB into the Oracle-hosted SODA collections, preserving JSON document structure.

4. Validation

  • Operational testing of Engage end-to-end: sign-in, OTP validation, core ERP workflows, and reporting.
  • Identification and remediation of one application-layer issue affecting OTP validation under the Oracle Mongo API (described in Section 7).
  • Sign-off against the original migration goals before promoting the new endpoint to production traffic.

Technical Implementation: ORDS and the Mongo API

The following section documents the actual installation and configuration steps performed by Kovaion’s engineering team to stand up the Oracle Database API for MongoDB for the Engage workload. Commands shown are taken from the production deployment runbook.

Prerequisites

  • Oracle Database with target pluggable database KOVPDB.
  • ORDS distribution unpacked at /u01/ORDS_HOME.
  • ORDS configuration directory at /u01/ords_config.
  • Network connectivity from the application tier to the database server on port 1521 (SQL*Net) and 27017 (Mongo wire protocol).

Step 1 – Validate Database Connectivity

Confirm the target PDB is reachable from the ORDS host before any configuration begins:

tnsping KOVPDB

A successful TNS ping against the KOVPDB service confirms listener registration and network path.

Step 2 – Install ORDS

Run the interactive installer against the configured ORDS_HOME:

export ORDS_HOME=/u01/ORDS_HOME
export PATH=$ORDS_HOME/bin:$PATH

ords --config /u01/ords_config install

During the interactive install, the SYS administrator credentials are supplied, the TNS connection to KOVPDB is selected, and ORDS is configured for HTTP access on port 8080 in standalone mode. On completion the runtime user (ORDS_PUBLIC_USER) is created in the database and the configuration folder is populated.

Step 3 – Create the Application Schema

A dedicated schema is created to host the Engage collections. The SODA_APP role is granted so the schema can act as a Simple Oracle Document Access container:

CREATE USER STAGE1_ENGAGE IDENTIFIED BY "WeLCome#123#"
DEFAULT TABLESPACE USERS
QUOTA UNLIMITED ON USERS;

GRANT CREATE SESSION TO STAGE1_ENGAGE;
GRANT SODA_APP TO STAGE1_ENGAGE;
GRANT db_developer_role, CREATE TABLE, CREATE VIEW, CREATE SEQUENCE,
CREATE PROCEDURE, CREATE JOB, CREATE USER, ALTER USER, DROP USER,
UNLIMITED TABLESPACE TO STAGE1_ENGAGE;

In production, schema passwords are managed through Kovaion’s standard secret-management process, the value above is illustrative.

Step 4 – Enable the Schema for ORDS

Enabling the schema for ORDS exposes it through REST and, in conjunction with the Mongo API setting, through the Mongo wire endpoint:

BEGIN
  ORDS.ENABLE_SCHEMA(
    p_enabled => TRUE,
    p_schema => 'STAGE1_ENGAGE'
  );
  COMMIT;
END;
/

Step 5 – Enable the Mongo API

Three configuration values activate the Mongo wire endpoint on the ORDS instance:

ords --config /u01/ords_config config set mongo.enabled true
ords --config /u01/ords_config config set mongo.port 27017
ords --config /u01/ords_config config set mongo.host 0.0.0.0
ords --config /u01/ords_config config set mongo.tls false

In the Engage staging environment TLS termination is handled at the ingress layer, so mongo.tls is set to false at the ORDS endpoint. For production traffic, TLS should be enabled directly on ORDS or fronted by a TLS-terminating proxy in line with the customer’s security policy.

Step 6 – Restart ORDS

Restart the ORDS process so the new Mongo settings take effect:

kill -9 <PID>
nohup ords --config /u01/ords_config serve > ords.out 2>&1 &

ORDS log output (ords.out) confirms successful initialisation and that the local pool /ords/ has resolved as VALID against the configured database.

Step 7 – Verify the Mongo Endpoint

A standard mongosh client validates connectivity, authentication and the SODA-backed namespace:

mongosh "mongodb://STAGE1_ENGAGE:WeLCome%23123%23@<host>:27017/STAGE1_ENGAGE?authMechanism=PLAIN&authSource=%24external&tls=false&loadBalanced=true&retryWrites=false"

On success, the shell drops into the STAGE1_ENGAGE> prompt – confirming that Engage’s existing Node.js MongoDB driver, configured with the same connection string, will be able to read and write documents against the Oracle Database without code changes.

Application-Layer Challenge: OTP Validation

During Validation, Engage’s sign-in flow surfaced a single, well-defined application-layer issue: OTP validation failed under the Oracle-backed Mongo API. This section captures the symptom, the root cause, and the engineering solution Kovaion put in place. It is included here both for transparency on the migration and because the same pattern is likely to recur in other MongoDB-to-Oracle migrations of MERN applications.

Symptom

On submission of an OTP at sign-in, the Fastify backend returned an Internal Server Error. The Mongo driver surfaced the underlying error from ORDS:

MongoServerError: The field name $expr is not a recognized operator.

The same OTP collection and the same aggregation pipeline had worked correctly against native MongoDB before cutover.

Root Cause

Engage’s original OTP validation used a MongoDB aggregation that combined a $match with $and / $or filters and a top-level $expr clause comparing the current time to the document’s expiration_time. The specific composition of $expr at the top level of the $match – rather than nested inside its own pipeline stage – was not supported by the Oracle Database API for MongoDB at the version in use. The aggregation was rejected at the operator-validation layer before any data was read.

Original aggregation (abridged)

let otp_table = fastify.mongo[slugdata].db.collection("user_OTP_details");
let otpDetails = await otp_table.aggregate([
  {
    $match: {
      $and: [
        {
          $or: [
            { email: typeof email === "string" ? email.toLowerCase() : email },
            { user_id: email },
            { phone: email }
          ]
        },
        { otp_code: password }
      ],
      $expr: { $lt: [new Date(), "$expiration_time"] }
    }
  }
]).toArray();

Solution: SQL-Based Query Layer via AlaSQL

Rather than rewrite every affected aggregation into a strictly-compatible Mongo pipeline (and risk further compatibility deltas elsewhere in the codebase), Kovaion introduced a thin, application-side query helper. The helper fetches documents from the underlying collection through the standard Mongo driver and then evaluates a SQL expression against an in-memory table using AlaSQL. The result is a stable, declarative query surface for the Engage application that is decoupled from the specific operator coverage of the Mongo API.

Helper implementation

export const executeSQLQuery = async (database, collectionName, sqlQuery, params = {}) => {
  try {
    // 1. Fetch collection data via the standard Mongo driver
    const collection = database.collection(collectionName);
    const data = await collection.find({}).toArray();

    // 2. Register the result set as an in-memory SQL table
    alasql.tables[collectionName] = { data };

    // 3. Bind named parameters into the query
    let finalQuery = sqlQuery;
    Object.entries(params).forEach(([key, value]) => {
      finalQuery = finalQuery.replace(
        new RegExp(`:${key}`, "g"),
        typeof value === "string" ? `'${value}'` : value
      );
    });

    // 4. Execute and return
    return alasql(finalQuery);
  } catch (err) {
    console.error("SQL Query Error:", err.message);
    throw err;
  }
};

OTP validation rewritten in SQL

SELECT *
FROM user_OTP_details
WHERE ( email = LOWER(:email)
   OR user_id = :email
   OR phone = :email )
  AND otp_code = :password
  AND expiration_time > NOW();

Call site

const otpRows = await executeSQLQuery(
  fastify.mongo[slugdata].db,
  "user_OTP_details",
  `SELECT *
   FROM user_OTP_details
   WHERE ( email = LOWER(:email)
      OR user_id = :email
      OR phone = :email )
     AND otp_code = :password
     AND expiration_time > NOW();`,
  { email, password }
);

Why this approach

  • Minimal surface change. The Mongo driver, connection string, and Oracle endpoint remain untouched; only the query construction is replaced.
  • Operator-coverage independence. The application no longer depends on the exact aggregation operator set supported by any specific version of the Mongo API.
  • Readability. SQL with named parameters is unambiguous for the security-sensitive OTP validation path and easier to review.
  • Forward path. The same helper can later be re-pointed to native Oracle SQL or JSON Duality views as Engage progresses through the Optimise and Innovate stages of Oracle’s value model – without changing the call sites.

Operational notes

  • The current helper performs an unfiltered find({}) before SQL evaluation, which is acceptable for small reference collections such as user_OTP_details but should be paired with a Mongo-side pre-filter for large collections.
  • Parameter substitution wraps strings in single quotes; production hardening adds explicit escaping or parameter binding to eliminate any injection surface for user-supplied values.
  • Where Engage workflows benefit from server-side execution, equivalent queries can be promoted to Oracle SQL views or JSON Duality views, leaving the application code unchanged thanks to the helper boundary.

Outcomes and Business Value

Technical outcomes

  • Engage runs end-to-end against an Oracle Database via the Oracle Database API for MongoDB, with no change to the JSON document model.
  • The application code path is preserved – the same MongoDB driver, the same connection idioms, the same collection and document interactions.
  • OTP validation, the single application-layer issue surfaced during validation, is resolved through a reusable SQL-based query helper that hardens the application against future operator-coverage variation.
  • The platform now sits on a converged Oracle Database, opening a forward path to JSON Duality, in-database analytics, and 23ai capabilities including AI Vector Search.

Business outcomes

  • A live, in-production reference workload (Engage) demonstrating the low-effort migration path under Oracle’s Partner Enablement Plan.
  • A repeatable runbook covering ORDS install, Mongo API enablement, schema provisioning, and application-layer remediation patterns.
  • Foundation for joint Oracle–Kovaion go-to-market activity, including marketing announcements and Oracle endorsement of Kovaion’s enhanced migration capability.
  • A new Kovaion service offering: MongoDB-to-Oracle migration for MERN-stack and document-database workloads, delivered by senior consulting engineers trained under Oracle’s 100–400 level enablement curriculum.

Lessons Learned and Best Practices

The following observations from the Engage migration are now part of Kovaion’s standard delivery playbook for MongoDB-to-Oracle engagements.

  • Treat the Mongo API as a first-class compatibility surface. Inventory the aggregation operators and pipeline patterns the application uses before cutover; flag any that compose at the top level of $match (such as $expr) for early testing.
  • Introduce an application-side query helper early. A thin abstraction over the driver – even a simple SQL-on-results helper such as the AlaSQL pattern used here – pays for itself the first time an operator behaves differently between native MongoDB and the Oracle endpoint.
  • Validate auth and OTP paths first. They are the highest-frequency, highest-sensitivity workflows in any ERP-style application; if they pass under the new endpoint, most of the remaining surface area follows quickly.
  • Keep the schema model unchanged in phase one. Resist the temptation to relationalise during migration. The low-effort path is fastest precisely because it defers re-modelling to the Optimise stage, where it can be done with measurement.
  • Document every ORDS configuration value. mongo.enabled, mongo.port, mongo.host, and mongo.tls all have direct production implications and should be captured in environment-specific runbooks rather than re-derived per deployment.
  • Plan the TLS story up front. The endpoint can be terminated at ORDS, at an upstream proxy, or both; the choice has implications for client driver configuration and certificate management that are easier to design than to retrofit.

Conclusion

The migration of Engage from MongoDB to the Oracle Database via the Oracle Database API for MongoDB is a concrete demonstration of what the Oracle Partner Enablement Plan is designed to produce: a partner with the depth to deliver, a workload that proves the methodology, and a repeatable path that other customers can now follow.

Kovaion has migrated its own production ERP workload using exactly the same approach it now offers to clients – under Oracle’s prescribed methodology, with Oracle’s training, and with the Oracle Database API for MongoDB as the technical enabler. The Engage migration confirms the low-effort path in a real operational setting, surfaces the application-layer patterns that matter, and provides the engineering artefacts to address them.

Together with Oracle, Kovaion is now positioned to take this capability to market – helping organisations move MongoDB workloads onto a converged Oracle Database, optimise them with Oracle’s tuning and JSON facilities, and innovate on top of Oracle Database.

Appendix A – Reference Command Sequence

For convenience, the full command sequence used to stand up the Oracle Database API for MongoDB on the Engage target environment is reproduced below.

Environment

export ORDS_HOME=/u01/ORDS_HOME
export PATH=$ORDS_HOME/bin:$PATH

Connectivity check

tnsping KOVPDB

ORDS install

ords --config /u01/ords_config install

Schema provisioning (SQL*Plus as SYS)

CREATE USER STAGE1_ENGAGE IDENTIFIED BY "WeLCome#123#"
DEFAULT TABLESPACE USERS QUOTA UNLIMITED ON USERS;

GRANT CREATE SESSION TO STAGE1_ENGAGE;
GRANT SODA_APP TO STAGE1_ENGAGE;

BEGIN
  ORDS.ENABLE_SCHEMA(p_enabled => TRUE, p_schema => 'STAGE1_ENGAGE');
  COMMIT;
END;
/

Mongo API enablement

ords --config /u01/ords_config config set mongo.enabled true
ords --config /u01/ords_config config set mongo.port 27017
ords --config /u01/ords_config config set mongo.host 0.0.0.0
ords --config /u01/ords_config config set mongo.tls false

Service start

nohup ords --config /u01/ords_config serve > ords.out 2>&1 &
tail -f ords.out

Client connection test

mongosh "mongodb://STAGE1_ENGAGE:WeLCome%23123%23@<host>:27017/STAGE1_ENGAGE?authMechanism=PLAIN&authSource=%24external&tls=false&loadBalanced=true&retryWrites=false"

Document prepared by Kovaion Consulting under the Oracle Partner Enablement Plan for MongoDB Migrations.