MongoDB is set to deprecate support for server-side JavaScript functions, a change already noted in the 8.0 compatibility release notes and community discussions. While not yet a migration blocker, this change is worth paying attention to, especially for teams considering long-term maintenance or planning migrations to other platforms like the Oracle Database.
Although I haven’t directly encountered this requirement in customer migrations yet, I anticipate it becoming more common as more MongoDB users upgrade to 8.0 or plan modernization efforts.
Workload Complexity Consideration
When evaluating migrations, I typically group workloads into three tiers:
- Simple – CRUD operations with minimal logic
- Medium – Involves limited aggregation or computation
- Complex – Includes custom logic, stored functions, or batch processing
Use of server-side JavaScript functions in MongoDB typically places the workload into the Medium or Complex category. These functions are often embedded in application logic and represent important business transformations or validations.
Migration Paths
To address this feature deprecation, customers have two primary options:
- Refactor using MongoDB’s Aggregation Pipelines
This is MongoDB’s recommended approach, and it works well when the logic is expressible in MQL. - Migrate logic to Oracle and invoke via the
$sqloperator
This is the preferred option when migrating to the Oracle Database, as it provides two powerful choices:- PL/SQL functions
- JavaScript functions using the Oracle Multilingual Engine (MLE)
Let’s walk through how you can approach both PL/SQL and MLE solutions in Oracle and invoke them from MongoDB API clients using the $sql operator.
MongoDB Server-Side JavaScript Example
db.system.js.insertOne({
_id: "echo",
value: function(x) { return x; }
});
echo("test");
Oracle PL/SQL Equivalent
CREATE OR REPLACE FUNCTION echo_plsql(name VARCHAR2 := NULL)
RETURN VARCHAR2
IS
whatname VARCHAR2(2000);
BEGIN
SELECT UPPER(name) INTO whatname FROM dual;
RETURN whatname;
END;
/
Oracle JavaScript (MLE) Equivalent
create or replace function echo_js_fn("name" varchar2)
return varchar2
as mle language javascript
{{
return name.toUpperCase();
}};
/
Testing via SQLPlus or SQLcl
VAR my_input VARCHAR2(100)
EXEC :my_input := 'Hello from SQL!'
SELECT echo_plsql(:my_input) AS echothisplsql FROM dual;
SELECT echo_js_fn(:my_input) AS echothismlejs FROM dual;
Using Oracle MongoDB API with $sql
From here on out, all examples are done with mongosh using the Oracle Database API for MongoDB 😮🤯
Single value example
let inputName = 'matt';
db.aggregate([
{
$sql: SELECT echo_plsql('${inputName}')
}
]);
db.aggregate([
{
$sql: SELECT echo_js_fn('${inputName}')
}
]);
List input example
let inputNameList = ['matt', 'nick', 'sunil'];
db.aggregate([
{
$sql: SELECT echo_js_fn('${inputNameList}')
}
]);
Working with a JSON Collection
db.echonames.insertMany([
{ "name": "Lance" },
{ "name": "Prakash" },
{ "name": "Virginia" },
{ "name": "Nick" },
{ "name": "Sunil" },
{ "name": "Matt" }
]);
Using PL/SQL Function
db.echonames.aggregate([
{
$sql: SELECT JSON_OBJECT( 'original' VALUE JSON_VALUE(v.data, '$.name'), 'echoed' VALUE echo_plsql(JSON_VALUE(v.data, '$.name')) ) FROM input v
}
]);
Using MLE JavaScript Function
db.echonames.aggregate([
{
$sql: SELECT JSON_OBJECT( 'original' VALUE JSON_VALUE(v.data, '$.name'), 'echoed' VALUE echo_js_fn(JSON_VALUE(v.data, '$.name')) ) FROM input v
}
]);
Final Thoughts
The deprecation of MongoDB server-side JavaScript may initially seem like a minor note in the release notes, but it represents a broader shift in how logic is managed in modern data platforms. Migrating this logic to the Oracle Database, using PL/SQL or JavaScript via MLE, offers a robust and maintainable path forward for customers considering consolidation or modernization.
For teams evaluating migration strategies, this is a great opportunity to clean up, centralize, and enhance server-side processing logic while maintaining compatibility through the Oracle Database API for MongoDB.
Leave a comment